forked from kscience/kmath
Merge pull request #293 from mipt-npm/commandertvis/ast-stability
Promote kmath-ast as experimental, mark AST Rendering and WASM with @UnstableKMathAPI
This commit is contained in:
commit
0f786e4f6f
@ -18,6 +18,10 @@ kotlin.js {
|
||||
}
|
||||
|
||||
kotlin.sourceSets {
|
||||
filter { it.name.contains("test", true) }
|
||||
.map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings)
|
||||
.forEach { it.useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI") }
|
||||
|
||||
commonMain {
|
||||
dependencies {
|
||||
api("com.github.h0tk3y.betterParse:better-parse:0.4.2")
|
||||
@ -54,7 +58,7 @@ tasks.dokkaHtml {
|
||||
}
|
||||
|
||||
readme {
|
||||
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
|
||||
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
|
||||
|
||||
feature(
|
||||
|
@ -29,7 +29,6 @@ import space.kscience.kmath.operations.RingOperations
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public object ArithmeticsEvaluator : Grammar<MST>() {
|
||||
// TODO replace with "...".toRegex() when better-parse 0.4.1 is released
|
||||
private val num: Token by regexToken("[\\d.]+(?:[eE][-+]?\\d+)?".toRegex())
|
||||
private val id: Token by regexToken("[a-z_A-Z][\\da-z_A-Z]*".toRegex())
|
||||
private val lpar: Token by literalToken("(")
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
|
||||
/**
|
||||
* [SyntaxRenderer] implementation for LaTeX.
|
||||
*
|
||||
@ -23,6 +25,7 @@ package space.kscience.kmath.ast.rendering
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public object LatexSyntaxRenderer : SyntaxRenderer {
|
||||
public override fun render(node: MathSyntax, output: Appendable): Unit = output.run {
|
||||
fun render(syntax: MathSyntax) = render(syntax, output)
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
|
||||
/**
|
||||
* [SyntaxRenderer] implementation for MathML.
|
||||
*
|
||||
@ -12,9 +14,10 @@ package space.kscience.kmath.ast.rendering
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public object MathMLSyntaxRenderer : SyntaxRenderer {
|
||||
public override fun render(node: MathSyntax, output: Appendable) {
|
||||
output.append("<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>")
|
||||
output.append("<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>")
|
||||
render0(node, output)
|
||||
output.append("</mrow></math>")
|
||||
}
|
||||
|
@ -6,12 +6,14 @@
|
||||
package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.expressions.MST
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
|
||||
/**
|
||||
* Renders [MST] to [MathSyntax].
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun interface MathRenderer {
|
||||
/**
|
||||
* Renders [MST] to [MathSyntax].
|
||||
@ -25,6 +27,7 @@ public fun interface MathRenderer {
|
||||
* @property features The applied features.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public open class FeaturedMathRenderer(public val features: List<RenderFeature>) : MathRenderer {
|
||||
public override fun render(mst: MST): MathSyntax {
|
||||
for (feature in features) feature.render(this, mst)?.let { return it }
|
||||
@ -48,6 +51,7 @@ public open class FeaturedMathRenderer(public val features: List<RenderFeature>)
|
||||
* @property stages The applied stages.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public open class FeaturedMathRendererWithPostProcess(
|
||||
features: List<RenderFeature>,
|
||||
public val stages: List<PostProcessStage>,
|
||||
|
@ -5,11 +5,14 @@
|
||||
|
||||
package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
|
||||
/**
|
||||
* Mathematical typography syntax node.
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public sealed class MathSyntax {
|
||||
/**
|
||||
* The parent node of this syntax node.
|
||||
@ -22,6 +25,7 @@ public sealed class MathSyntax {
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public sealed class TerminalSyntax : MathSyntax()
|
||||
|
||||
/**
|
||||
@ -29,6 +33,7 @@ public sealed class TerminalSyntax : MathSyntax()
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public sealed class OperationSyntax : MathSyntax() {
|
||||
/**
|
||||
* The operation token.
|
||||
@ -41,6 +46,7 @@ public sealed class OperationSyntax : MathSyntax() {
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public sealed class UnarySyntax : OperationSyntax() {
|
||||
/**
|
||||
* The operand of this node.
|
||||
@ -53,6 +59,7 @@ public sealed class UnarySyntax : OperationSyntax() {
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public sealed class BinarySyntax : OperationSyntax() {
|
||||
/**
|
||||
* The left-hand side operand.
|
||||
@ -71,6 +78,7 @@ public sealed class BinarySyntax : OperationSyntax() {
|
||||
* @property string The digits of number.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class NumberSyntax(public var string: String) : TerminalSyntax()
|
||||
|
||||
/**
|
||||
@ -79,6 +87,7 @@ public data class NumberSyntax(public var string: String) : TerminalSyntax()
|
||||
* @property string The symbol.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class SymbolSyntax(public var string: String) : TerminalSyntax()
|
||||
|
||||
/**
|
||||
@ -89,6 +98,7 @@ public data class SymbolSyntax(public var string: String) : TerminalSyntax()
|
||||
* @see UnaryOperatorSyntax
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
|
||||
|
||||
/**
|
||||
@ -97,6 +107,7 @@ public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
|
||||
* @property kind The kind of symbol.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax() {
|
||||
/**
|
||||
* The kind of symbol.
|
||||
@ -121,6 +132,7 @@ public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax()
|
||||
* @property parentheses Whether the operand should be wrapped with parentheses.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class OperandSyntax(
|
||||
public val operand: MathSyntax,
|
||||
public var parentheses: Boolean,
|
||||
@ -136,6 +148,7 @@ public data class OperandSyntax(
|
||||
* @property prefix The prefix.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class UnaryOperatorSyntax(
|
||||
public override val operation: String,
|
||||
public var prefix: MathSyntax,
|
||||
@ -151,6 +164,7 @@ public data class UnaryOperatorSyntax(
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class UnaryPlusSyntax(
|
||||
public override val operation: String,
|
||||
public override val operand: OperandSyntax,
|
||||
@ -165,6 +179,7 @@ public data class UnaryPlusSyntax(
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class UnaryMinusSyntax(
|
||||
public override val operation: String,
|
||||
public override val operand: OperandSyntax,
|
||||
@ -180,6 +195,7 @@ public data class UnaryMinusSyntax(
|
||||
* @property operand The radicand.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class RadicalSyntax(
|
||||
public override val operation: String,
|
||||
public override val operand: MathSyntax,
|
||||
@ -197,6 +213,7 @@ public data class RadicalSyntax(
|
||||
* (*e<sup>x</sup>*).
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class ExponentSyntax(
|
||||
public override val operation: String,
|
||||
public override val operand: OperandSyntax,
|
||||
@ -214,6 +231,7 @@ public data class ExponentSyntax(
|
||||
* @property right The superscript.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class SuperscriptSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: MathSyntax,
|
||||
@ -232,6 +250,7 @@ public data class SuperscriptSyntax(
|
||||
* @property right The subscript.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class SubscriptSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: MathSyntax,
|
||||
@ -249,6 +268,7 @@ public data class SubscriptSyntax(
|
||||
* @property prefix The prefix.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class BinaryOperatorSyntax(
|
||||
public override val operation: String,
|
||||
public var prefix: MathSyntax,
|
||||
@ -268,6 +288,7 @@ public data class BinaryOperatorSyntax(
|
||||
* @param right The addend.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class BinaryPlusSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: OperandSyntax,
|
||||
@ -286,6 +307,7 @@ public data class BinaryPlusSyntax(
|
||||
* @param right The subtrahend.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class BinaryMinusSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: OperandSyntax,
|
||||
@ -304,6 +326,7 @@ public data class BinaryMinusSyntax(
|
||||
* @property right The denominator.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class FractionSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: MathSyntax,
|
||||
@ -322,6 +345,7 @@ public data class FractionSyntax(
|
||||
* @property right The radicand.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class RadicalWithIndexSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: MathSyntax,
|
||||
@ -341,6 +365,7 @@ public data class RadicalWithIndexSyntax(
|
||||
* @property times whether the times (×) symbol should be used.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public data class MultiplicationSyntax(
|
||||
public override val operation: String,
|
||||
public override val left: OperandSyntax,
|
||||
|
@ -5,12 +5,15 @@
|
||||
|
||||
package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
|
||||
/**
|
||||
* Abstraction of writing [MathSyntax] as a string of an actual markup language. Typical implementation should
|
||||
* involve traversal of MathSyntax with handling each its subtype.
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun interface SyntaxRenderer {
|
||||
/**
|
||||
* Renders the [MathSyntax] to [output].
|
||||
@ -23,6 +26,7 @@ public fun interface SyntaxRenderer {
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun SyntaxRenderer.renderWithStringBuilder(node: MathSyntax): String {
|
||||
val sb = StringBuilder()
|
||||
render(node, sb)
|
||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.ast.rendering.FeaturedMathRenderer.RenderFeature
|
||||
import space.kscience.kmath.expressions.MST
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@ -15,11 +16,12 @@ import kotlin.reflect.KClass
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public object PrintSymbolic : RenderFeature {
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Symbolic) return null
|
||||
return SymbolSyntax(string = node.value)
|
||||
}
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): SymbolSyntax? =
|
||||
if (node !is MST.Symbolic) null
|
||||
else
|
||||
SymbolSyntax(string = node.value)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,25 +29,25 @@ public object PrintSymbolic : RenderFeature {
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public object PrintNumeric : RenderFeature {
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Numeric) return null
|
||||
return NumberSyntax(string = node.value.toString())
|
||||
}
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): NumberSyntax? = if (node !is MST.Numeric)
|
||||
null
|
||||
else
|
||||
NumberSyntax(string = node.value.toString())
|
||||
}
|
||||
|
||||
private fun printSignedNumberString(s: String): MathSyntax {
|
||||
if (s.startsWith('-'))
|
||||
return UnaryMinusSyntax(
|
||||
operation = GroupOperations.MINUS_OPERATION,
|
||||
operand = OperandSyntax(
|
||||
operand = NumberSyntax(string = s.removePrefix("-")),
|
||||
parentheses = true,
|
||||
),
|
||||
)
|
||||
|
||||
return NumberSyntax(string = s)
|
||||
}
|
||||
@UnstableKMathAPI
|
||||
private fun printSignedNumberString(s: String): MathSyntax = if (s.startsWith('-'))
|
||||
UnaryMinusSyntax(
|
||||
operation = GroupOperations.MINUS_OPERATION,
|
||||
operand = OperandSyntax(
|
||||
operand = NumberSyntax(string = s.removePrefix("-")),
|
||||
parentheses = true,
|
||||
),
|
||||
)
|
||||
else
|
||||
NumberSyntax(string = s)
|
||||
|
||||
/**
|
||||
* Special printing for numeric types which are printed in form of
|
||||
@ -53,9 +55,11 @@ private fun printSignedNumberString(s: String): MathSyntax {
|
||||
*
|
||||
* @property types The suitable types.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature {
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Numeric || node.value::class !in types) return null
|
||||
|
||||
val toString = when (val v = node.value) {
|
||||
is Float -> v.multiplatformToString()
|
||||
is Double -> v.multiplatformToString()
|
||||
@ -110,11 +114,13 @@ public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : Rend
|
||||
*
|
||||
* @property types The suitable types.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature {
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Numeric || node.value::class !in types) return null
|
||||
return printSignedNumberString(node.value.toString())
|
||||
}
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? =
|
||||
if (node !is MST.Numeric || node.value::class !in types)
|
||||
null
|
||||
else
|
||||
printSignedNumberString(node.value.toString())
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
@ -130,11 +136,13 @@ public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : Re
|
||||
*
|
||||
* @property symbols The allowed symbols.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Symbolic || node.value !in symbols) return null
|
||||
return SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI)
|
||||
}
|
||||
public override fun render(renderer: FeaturedMathRenderer, node: MST): SpecialSymbolSyntax? =
|
||||
if (node !is MST.Symbolic || node.value !in symbols)
|
||||
null
|
||||
else
|
||||
SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
@ -150,16 +158,18 @@ public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
||||
*
|
||||
* @param operations the allowed operations. If `null`, any operation is accepted.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public abstract class Unary(public val operations: Collection<String>?) : RenderFeature {
|
||||
/**
|
||||
* The actual render function.
|
||||
* The actual render function specialized for [MST.Unary].
|
||||
*/
|
||||
protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax?
|
||||
protected abstract fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax?
|
||||
|
||||
public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Unary || operations != null && node.operation !in operations) return null
|
||||
return render0(renderer, node)
|
||||
}
|
||||
public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? =
|
||||
if (node !is MST.Unary || operations != null && node.operation !in operations)
|
||||
null
|
||||
else
|
||||
renderUnary(renderer, node)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,164 +178,258 @@ public abstract class Unary(public val operations: Collection<String>?) : Render
|
||||
*
|
||||
* @property operations the allowed operations. If `null`, any operation is accepted.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public abstract class Binary(public val operations: Collection<String>?) : RenderFeature {
|
||||
/**
|
||||
* The actual render function.
|
||||
* The actual render function specialized for [MST.Binary].
|
||||
*/
|
||||
protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax?
|
||||
protected abstract fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax?
|
||||
|
||||
public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
|
||||
if (node !is MST.Binary || operations != null && node.operation !in operations) return null
|
||||
return render0(renderer, node)
|
||||
return renderBinary(renderer, node)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [BinaryPlusSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryPlusSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(parent.render(node.left), true),
|
||||
right = OperandSyntax(parent.render(node.right), true),
|
||||
)
|
||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryPlusSyntax =
|
||||
BinaryPlusSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(parent.render(node.left), true),
|
||||
right = OperandSyntax(parent.render(node.right), true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [GroupOperations.PLUS_OPERATION].
|
||||
*/
|
||||
public val Default: BinaryPlus = BinaryPlus(setOf(GroupOperations.PLUS_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [BinaryMinusSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryMinusSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
|
||||
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
|
||||
)
|
||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryMinusSyntax =
|
||||
BinaryMinusSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
|
||||
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [GroupOperations.MINUS_OPERATION].
|
||||
*/
|
||||
public val Default: BinaryMinus = BinaryMinus(setOf(GroupOperations.MINUS_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unary nodes by producing [UnaryPlusSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryPlusSyntax(
|
||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryPlusSyntax = UnaryPlusSyntax(
|
||||
operation = node.operation,
|
||||
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [GroupOperations.PLUS_OPERATION].
|
||||
*/
|
||||
public val Default: UnaryPlus = UnaryPlus(setOf(GroupOperations.PLUS_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [UnaryMinusSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryMinusSyntax(
|
||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryMinusSyntax = UnaryMinusSyntax(
|
||||
operation = node.operation,
|
||||
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [GroupOperations.MINUS_OPERATION].
|
||||
*/
|
||||
public val Default: UnaryMinus = UnaryMinus(setOf(GroupOperations.MINUS_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [FractionSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = FractionSyntax(
|
||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
|
||||
operation = node.operation,
|
||||
left = parent.render(node.left),
|
||||
right = parent.render(node.right),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [FieldOperations.DIV_OPERATION].
|
||||
*/
|
||||
public val Default: Fraction = Fraction(setOf(FieldOperations.DIV_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [BinaryOperatorSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class BinaryOperator(operations: Collection<String>?) : Binary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryOperatorSyntax(
|
||||
operation = node.operation,
|
||||
prefix = OperatorNameSyntax(name = node.operation),
|
||||
left = parent.render(node.left),
|
||||
right = parent.render(node.right),
|
||||
)
|
||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryOperatorSyntax =
|
||||
BinaryOperatorSyntax(
|
||||
operation = node.operation,
|
||||
prefix = OperatorNameSyntax(name = node.operation),
|
||||
left = parent.render(node.left),
|
||||
right = parent.render(node.right),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with `null`.
|
||||
*/
|
||||
public val Default: BinaryOperator = BinaryOperator(null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unary nodes by producing [UnaryOperatorSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class UnaryOperator(operations: Collection<String>?) : Unary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax(
|
||||
operation = node.operation,
|
||||
prefix = OperatorNameSyntax(node.operation),
|
||||
operand = OperandSyntax(parent.render(node.value), true),
|
||||
)
|
||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
||||
UnaryOperatorSyntax(
|
||||
operation = node.operation,
|
||||
prefix = OperatorNameSyntax(node.operation),
|
||||
operand = OperandSyntax(parent.render(node.value), true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with `null`.
|
||||
*/
|
||||
public val Default: UnaryOperator = UnaryOperator(null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [SuperscriptSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class Power(operations: Collection<String>?) : Binary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = SuperscriptSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(parent.render(node.left), true),
|
||||
right = OperandSyntax(parent.render(node.right), true),
|
||||
)
|
||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): SuperscriptSyntax =
|
||||
SuperscriptSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(parent.render(node.left), true),
|
||||
right = OperandSyntax(parent.render(node.right), true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [PowerOperations.POW_OPERATION].
|
||||
*/
|
||||
public val Default: Power = Power(setOf(PowerOperations.POW_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [RadicalSyntax] with no index.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class SquareRoot(operations: Collection<String>?) : Unary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax =
|
||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): RadicalSyntax =
|
||||
RadicalSyntax(operation = node.operation, operand = parent.render(node.value))
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [PowerOperations.SQRT_OPERATION].
|
||||
*/
|
||||
public val Default: SquareRoot = SquareRoot(setOf(PowerOperations.SQRT_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unary nodes by producing [ExponentSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = ExponentSyntax(
|
||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): ExponentSyntax = ExponentSyntax(
|
||||
operation = node.operation,
|
||||
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||
useOperatorForm = true,
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [ExponentialOperations.EXP_OPERATION].
|
||||
*/
|
||||
public val Default: Exponent = Exponent(setOf(ExponentialOperations.EXP_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing [MultiplicationSyntax].
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class Multiplication(operations: Collection<String>?) : Binary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = MultiplicationSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
|
||||
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
|
||||
times = true,
|
||||
)
|
||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): MultiplicationSyntax =
|
||||
MultiplicationSyntax(
|
||||
operation = node.operation,
|
||||
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
|
||||
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
|
||||
times = true,
|
||||
)
|
||||
|
||||
public companion object {
|
||||
public val Default: Multiplication = Multiplication(setOf(
|
||||
RingOperations.TIMES_OPERATION,
|
||||
))
|
||||
/**
|
||||
* The default instance configured with [RingOperations.TIMES_OPERATION].
|
||||
*/
|
||||
public val Default: Multiplication = Multiplication(setOf(RingOperations.TIMES_OPERATION))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] (like *sin<sup>-1</sup>*) with removing the `a`
|
||||
* prefix of operation ID.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
|
||||
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax(
|
||||
operation = node.operation,
|
||||
prefix = SuperscriptSyntax(
|
||||
operation = PowerOperations.POW_OPERATION,
|
||||
left = OperatorNameSyntax(name = node.operation.removePrefix("a")),
|
||||
right = UnaryMinusSyntax(
|
||||
operation = GroupOperations.MINUS_OPERATION,
|
||||
operand = OperandSyntax(operand = NumberSyntax(string = "1"), parentheses = true),
|
||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
||||
UnaryOperatorSyntax(
|
||||
operation = node.operation,
|
||||
prefix = SuperscriptSyntax(
|
||||
operation = PowerOperations.POW_OPERATION,
|
||||
left = OperatorNameSyntax(name = node.operation.removePrefix("a")),
|
||||
right = UnaryMinusSyntax(
|
||||
operation = GroupOperations.MINUS_OPERATION,
|
||||
operand = OperandSyntax(operand = NumberSyntax(string = "1"), parentheses = true),
|
||||
),
|
||||
),
|
||||
),
|
||||
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||
)
|
||||
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||
)
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
|
||||
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION],
|
||||
* [ExponentialOperations.ACOSH_OPERATION], [ExponentialOperations.ASINH_OPERATION], and
|
||||
* [ExponentialOperations.ATANH_OPERATION].
|
||||
*/
|
||||
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
|
||||
TrigonometricOperations.ACOS_OPERATION,
|
||||
TrigonometricOperations.ASIN_OPERATION,
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.ast.rendering
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.FieldOperations
|
||||
import space.kscience.kmath.operations.GroupOperations
|
||||
import space.kscience.kmath.operations.PowerOperations
|
||||
@ -15,6 +16,7 @@ import space.kscience.kmath.operations.RingOperations
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostProcessStage {
|
||||
public override fun perform(node: MathSyntax): Unit = when (node) {
|
||||
is NumberSyntax -> Unit
|
||||
@ -88,6 +90,7 @@ public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostPro
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessStage {
|
||||
private fun perform0(node: MathSyntax): Boolean {
|
||||
return when (node) {
|
||||
@ -129,6 +132,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
|
||||
* @property precedenceFunction Returns the precedence number for syntax node. Higher number is lower priority.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) -> Int) :
|
||||
FeaturedMathRendererWithPostProcess.PostProcessStage {
|
||||
public override fun perform(node: MathSyntax): Unit = when (node) {
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
package space.kscience.kmath.ast
|
||||
|
||||
import space.kscience.kmath.ast.parseMath
|
||||
import space.kscience.kmath.expressions.evaluate
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import kotlin.test.Test
|
||||
|
@ -30,17 +30,17 @@ internal object TestUtils {
|
||||
)
|
||||
|
||||
internal fun testMathML(mst: MST, expectedMathML: String) = assertEquals(
|
||||
expected = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
|
||||
expected = "<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
|
||||
actual = mathML(mst),
|
||||
)
|
||||
|
||||
internal fun testMathML(expression: String, expectedMathML: String) = assertEquals(
|
||||
expected = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
|
||||
expected = "<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
|
||||
actual = mathML(expression.parseMath()),
|
||||
)
|
||||
|
||||
internal fun testMathML(expression: MathSyntax, expectedMathML: String) = assertEquals(
|
||||
expected = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
|
||||
expected = "<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
|
||||
actual = MathMLSyntaxRenderer.renderWithStringBuilder(expression),
|
||||
)
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("INTERFACE_WITH_SUPERCLASS",
|
||||
@file:Suppress(
|
||||
"INTERFACE_WITH_SUPERCLASS",
|
||||
"OVERRIDING_FINAL_MEMBER",
|
||||
"RETURN_TYPE_MISMATCH_ON_OVERRIDE",
|
||||
"CONFLICTING_OVERLOADS",
|
||||
|
@ -26,7 +26,7 @@ internal sealed class WasmBuilder<T>(
|
||||
val keys: MutableList<String> = mutableListOf()
|
||||
lateinit var ctx: BinaryenModule
|
||||
|
||||
open fun visitSymbolic(mst: MST.Symbolic): ExpressionRef {
|
||||
open fun visitSymbolic(mst: Symbolic): ExpressionRef {
|
||||
try {
|
||||
algebra.bindSymbol(mst.value)
|
||||
} catch (ignored: Throwable) {
|
||||
|
@ -10,6 +10,7 @@ import space.kscience.kmath.expressions.Expression
|
||||
import space.kscience.kmath.expressions.MST
|
||||
import space.kscience.kmath.expressions.invoke
|
||||
import space.kscience.kmath.misc.Symbol
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.IntRing
|
||||
import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
|
||||
@ -20,6 +21,7 @@ import space.kscience.kmath.wasm.internal.IntWasmBuilder
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun DoubleField.expression(mst: MST): Expression<Double> =
|
||||
DoubleWasmBuilder(mst).instance
|
||||
|
||||
@ -28,6 +30,7 @@ public fun DoubleField.expression(mst: MST): Expression<Double> =
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun IntRing.expression(mst: MST): Expression<Int> =
|
||||
IntWasmBuilder(mst).instance
|
||||
|
||||
@ -36,6 +39,7 @@ public fun IntRing.expression(mst: MST): Expression<Int> =
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun MST.compileToExpression(algebra: IntRing): Expression<Int> = compileWith(algebra)
|
||||
|
||||
|
||||
@ -44,6 +48,7 @@ public fun MST.compileToExpression(algebra: IntRing): Expression<Int> = compileW
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
|
||||
compileToExpression(algebra).invoke(arguments)
|
||||
|
||||
@ -53,6 +58,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int =
|
||||
compileToExpression(algebra)(*arguments)
|
||||
|
||||
@ -61,6 +67,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = compileWith(algebra)
|
||||
|
||||
|
||||
@ -69,6 +76,7 @@ public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = c
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double =
|
||||
compileToExpression(algebra).invoke(arguments)
|
||||
|
||||
@ -78,5 +86,6 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double =
|
||||
compileToExpression(algebra).invoke(*arguments)
|
||||
|
@ -342,8 +342,8 @@ internal class AsmBuilder<T>(
|
||||
val MAP_INTRINSICS_TYPE: Type by lazy { getObjectType("space/kscience/kmath/asm/internal/MapIntrinsics") }
|
||||
|
||||
/**
|
||||
* ASM Type for [kscience.kmath.expressions.Symbol].
|
||||
* ASM Type for [space.kscience.kmath.misc.Symbol].
|
||||
*/
|
||||
val SYMBOL_TYPE: Type by lazy { getObjectType("space/kscience/kmath/expressions/Symbol") }
|
||||
val SYMBOL_TYPE: Type by lazy { getObjectType("space/kscience/kmath/misc/Symbol") }
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.(
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) }
|
||||
internal fun MethodVisitor.label(): Label = Label().also(::visitLabel)
|
||||
|
||||
/**
|
||||
* Creates a class name for [Expression] subclassed to implement [mst] provided.
|
||||
|
Loading…
Reference in New Issue
Block a user