From 3e7c9d8dce15fd5c17747aba953147e05c13c4f4 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sat, 28 Nov 2020 13:33:05 +0700 Subject: [PATCH 01/39] Rework unary/binary operation API --- .../kotlin/kscience/kmath/ast/MST.kt | 19 ++- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 126 +++++++++--------- .../kscience/kmath/ast/MstExpression.kt | 6 +- .../kmath/asm/TestAsmSpecialization.kt | 15 +-- .../kotlin/kscience/kmath/ast/ParserTest.kt | 16 +-- .../FunctionalExpressionAlgebra.kt | 76 +++++------ .../kscience/kmath/linear/MatrixContext.kt | 9 +- .../kscience/kmath/operations/Algebra.kt | 72 +++++----- .../kmath/operations/NumberAlgebra.kt | 58 ++++---- 9 files changed, 194 insertions(+), 203 deletions(-) diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt index f312323b9..cc3d38f9c 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt @@ -55,24 +55,23 @@ public sealed class MST { public fun Algebra.evaluate(node: MST): T = when (node) { is MST.Numeric -> (this as? NumericAlgebra)?.number(node.value) ?: error("Numeric nodes are not supported by $this") + is MST.Symbolic -> symbol(node.value) - is MST.Unary -> unaryOperation(node.operation, evaluate(node.value)) + is MST.Unary -> unaryOperation(node.operation)(evaluate(node.value)) + is MST.Binary -> when { - this !is NumericAlgebra -> binaryOperation(node.operation, evaluate(node.left), evaluate(node.right)) + this !is NumericAlgebra -> binaryOperation(node.operation)(evaluate(node.left), evaluate(node.right)) node.left is MST.Numeric && node.right is MST.Numeric -> { - val number = RealField.binaryOperation( - node.operation, - node.left.value.toDouble(), - node.right.value.toDouble() - ) + val number = RealField + .binaryOperation(node.operation)(node.left.value.toDouble(), node.right.value.toDouble()) number(number) } - node.left is MST.Numeric -> leftSideNumberOperation(node.operation, node.left.value, evaluate(node.right)) - node.right is MST.Numeric -> rightSideNumberOperation(node.operation, evaluate(node.left), node.right.value) - else -> binaryOperation(node.operation, evaluate(node.left), evaluate(node.right)) + node.left is MST.Numeric -> leftSideNumberOperation(node.operation)(node.left.value, evaluate(node.right)) + node.right is MST.Numeric -> rightSideNumberOperation(node.operation)(evaluate(node.left), node.right.value) + else -> binaryOperation(node.operation)(evaluate(node.left), evaluate(node.right)) } } diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index 6ee6ab9af..cea708342 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -6,115 +6,111 @@ import kscience.kmath.operations.* * [Algebra] over [MST] nodes. */ public object MstAlgebra : NumericAlgebra { - override fun number(value: Number): MST.Numeric = MST.Numeric(value) + public override fun number(value: Number): MST.Numeric = MST.Numeric(value) - override fun symbol(value: String): MST.Symbolic = MST.Symbolic(value) + public override fun symbol(value: String): MST.Symbolic = MST.Symbolic(value) - override fun unaryOperation(operation: String, arg: MST): MST.Unary = - MST.Unary(operation, arg) + public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = { arg -> MST.Unary(operation, arg) } - override fun binaryOperation(operation: String, left: MST, right: MST): MST.Binary = - MST.Binary(operation, left, right) + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = + { left, right -> MST.Binary(operation, left, right) } } /** * [Space] over [MST] nodes. */ public object MstSpace : Space, NumericAlgebra { - override val zero: MST.Numeric by lazy { number(0.0) } + public override val zero: MST.Numeric by lazy { number(0.0) } - override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) - override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) - override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION, a, b) - override fun multiply(a: MST, k: Number): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION, a, number(k)) + public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) + public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) + override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) + override fun multiply(a: MST, k: Number): MST = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) - override fun binaryOperation(operation: String, left: MST, right: MST): MST.Binary = - MstAlgebra.binaryOperation(operation, left, right) + override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + MstAlgebra.binaryOperation(operation) - override fun unaryOperation(operation: String, arg: MST): MST.Unary = MstAlgebra.unaryOperation(operation, arg) + override fun unaryOperation(operation: String): (arg: MST) -> MST = MstAlgebra.unaryOperation(operation) } /** * [Ring] over [MST] nodes. */ public object MstRing : Ring, NumericAlgebra { - override val zero: MST.Numeric + override val zero: MST get() = MstSpace.zero + override val one: MST = number(1.0) - override val one: MST.Numeric by lazy { number(1.0) } + public override fun number(value: Number): MST = MstSpace.number(value) + public override fun symbol(value: String): MST = MstSpace.symbol(value) + public override fun add(a: MST, b: MST): MST = MstSpace.add(a, b) + public override fun multiply(a: MST, k: Number): MST = MstSpace.multiply(a, k) + public override fun multiply(a: MST, b: MST): MST = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) - override fun number(value: Number): MST.Numeric = MstSpace.number(value) - override fun symbol(value: String): MST.Symbolic = MstSpace.symbol(value) - override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) - override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) - override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION, a, b) + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + MstSpace.binaryOperation(operation) - override fun binaryOperation(operation: String, left: MST, right: MST): MST.Binary = - MstSpace.binaryOperation(operation, left, right) - - override fun unaryOperation(operation: String, arg: MST): MST.Unary = MstSpace.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: MST) -> MST = MstAlgebra.unaryOperation(operation) } /** * [Field] over [MST] nodes. */ public object MstField : Field { - public override val zero: MST.Numeric + public override val zero: MST get() = MstRing.zero - public override val one: MST.Numeric + public override val one: MST get() = MstRing.one - public override fun symbol(value: String): MST.Symbolic = MstRing.symbol(value) - public override fun number(value: Number): MST.Numeric = MstRing.number(value) - public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b) - public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) - public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) - public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION, a, b) + public override fun symbol(value: String): MST = MstRing.symbol(value) + public override fun number(value: Number): MST = MstRing.number(value) + public override fun add(a: MST, b: MST): MST = MstRing.add(a, b) + public override fun multiply(a: MST, k: Number): MST = MstRing.multiply(a, k) + public override fun multiply(a: MST, b: MST): MST = MstRing.multiply(a, b) + public override fun divide(a: MST, b: MST): MST = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) - public override fun binaryOperation(operation: String, left: MST, right: MST): MST.Binary = - MstRing.binaryOperation(operation, left, right) + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + MstRing.binaryOperation(operation) - override fun unaryOperation(operation: String, arg: MST): MST.Unary = MstRing.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: MST) -> MST = MstRing.unaryOperation(operation) } /** * [ExtendedField] over [MST] nodes. */ public object MstExtendedField : ExtendedField { - override val zero: MST.Numeric + public override val zero: MST get() = MstField.zero - override val one: MST.Numeric + public override val one: MST get() = MstField.one - override fun symbol(value: String): MST.Symbolic = MstField.symbol(value) - override fun number(value: Number): MST.Numeric = MstField.number(value) - override fun sin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) - override fun cos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.COS_OPERATION, arg) - override fun tan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.TAN_OPERATION, arg) - override fun asin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg) - override fun acos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg) - override fun atan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg) - override fun sinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.SINH_OPERATION, arg) - override fun cosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.COSH_OPERATION, arg) - override fun tanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.TANH_OPERATION, arg) - override fun asinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ASINH_OPERATION, arg) - override fun acosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ACOSH_OPERATION, arg) - override fun atanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ATANH_OPERATION, arg) - override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b) - override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) - override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) - override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b) + public override fun symbol(value: String): MST = MstField.symbol(value) + public override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) + public override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) + public override fun tan(arg: MST): MST = unaryOperation(TrigonometricOperations.TAN_OPERATION)(arg) + public override fun asin(arg: MST): MST = unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) + public override fun acos(arg: MST): MST = unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) + public override fun atan(arg: MST): MST = unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) + public override fun sinh(arg: MST): MST = unaryOperation(HyperbolicOperations.SINH_OPERATION)(arg) + public override fun cosh(arg: MST): MST = unaryOperation(HyperbolicOperations.COSH_OPERATION)(arg) + public override fun tanh(arg: MST): MST = unaryOperation(HyperbolicOperations.TANH_OPERATION)(arg) + public override fun asinh(arg: MST): MST = unaryOperation(HyperbolicOperations.ASINH_OPERATION)(arg) + public override fun acosh(arg: MST): MST = unaryOperation(HyperbolicOperations.ACOSH_OPERATION)(arg) + public override fun atanh(arg: MST): MST = unaryOperation(HyperbolicOperations.ATANH_OPERATION)(arg) + public override fun add(a: MST, b: MST): MST = MstField.add(a, b) + public override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k) + public override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b) + public override fun divide(a: MST, b: MST): MST = MstField.divide(a, b) + public override fun power(arg: MST, pow: Number): MST = binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) + public override fun exp(arg: MST): MST = unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) + public override fun ln(arg: MST): MST = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) - override fun power(arg: MST, pow: Number): MST.Binary = - binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow)) + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + MstField.binaryOperation(operation) - override fun exp(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.EXP_OPERATION, arg) - override fun ln(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.LN_OPERATION, arg) - - override fun binaryOperation(operation: String, left: MST, right: MST): MST.Binary = - MstField.binaryOperation(operation, left, right) - - override fun unaryOperation(operation: String, arg: MST): MST.Unary = MstField.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: MST) -> MST = MstField.unaryOperation(operation) + override fun unaryOperation(operation: String, arg: MST): MST.Unary = + MST.Unary(operation, arg) } diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt index f68e3f5f8..8a99fd2f4 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt @@ -16,10 +16,8 @@ import kotlin.contracts.contract public class MstExpression>(public val algebra: A, public val mst: MST) : Expression { private inner class InnerAlgebra(val arguments: Map) : NumericAlgebra { override fun symbol(value: String): T = arguments[StringSymbol(value)] ?: algebra.symbol(value) - override fun unaryOperation(operation: String, arg: T): T = algebra.unaryOperation(operation, arg) - - override fun binaryOperation(operation: String, left: T, right: T): T = - algebra.binaryOperation(operation, left, right) + override fun unaryOperation(operation: String): (arg: T) -> T = algebra.unaryOperation(operation) + override fun binaryOperation(operation: String): (left: T, right: T) -> T = algebra.binaryOperation(operation) @Suppress("UNCHECKED_CAST") override fun number(value: Number): T = if (algebra is NumericAlgebra<*>) diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt index 8f8175acd..eb5a1c8f3 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt @@ -1,6 +1,5 @@ package kscience.kmath.asm -import kscience.kmath.asm.compile import kscience.kmath.ast.mstInField import kscience.kmath.expressions.invoke import kscience.kmath.operations.RealField @@ -10,44 +9,44 @@ import kotlin.test.assertEquals internal class TestAsmSpecialization { @Test fun testUnaryPlus() { - val expr = RealField.mstInField { unaryOperation("+", symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperation("+")(symbol("x")) }.compile() assertEquals(2.0, expr("x" to 2.0)) } @Test fun testUnaryMinus() { - val expr = RealField.mstInField { unaryOperation("-", symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperation("-")(symbol("x")) }.compile() assertEquals(-2.0, expr("x" to 2.0)) } @Test fun testAdd() { - val expr = RealField.mstInField { binaryOperation("+", symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperation("+")(symbol("x"), symbol("x")) }.compile() assertEquals(4.0, expr("x" to 2.0)) } @Test fun testSine() { - val expr = RealField.mstInField { unaryOperation("sin", symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperation("sin")(symbol("x")) }.compile() assertEquals(0.0, expr("x" to 0.0)) } @Test fun testMinus() { - val expr = RealField.mstInField { binaryOperation("-", symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperation("-")(symbol("x"), symbol("x")) }.compile() assertEquals(0.0, expr("x" to 2.0)) } @Test fun testDivide() { - val expr = RealField.mstInField { binaryOperation("/", symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperation("/")(symbol("x"), symbol("x")) }.compile() assertEquals(1.0, expr("x" to 2.0)) } @Test fun testPower() { val expr = RealField - .mstInField { binaryOperation("power", symbol("x"), number(2)) } + .mstInField { binaryOperation("power")(symbol("x"), number(2)) } .compile() assertEquals(4.0, expr("x" to 2.0)) diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt index 2dc24597e..e2029ce19 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt @@ -1,8 +1,5 @@ package kscience.kmath.ast -import kscience.kmath.ast.evaluate -import kscience.kmath.ast.mstInField -import kscience.kmath.ast.parseMath import kscience.kmath.expressions.invoke import kscience.kmath.operations.Algebra import kscience.kmath.operations.Complex @@ -45,12 +42,15 @@ internal class ParserTest { val magicalAlgebra = object : Algebra { override fun symbol(value: String): String = value - override fun unaryOperation(operation: String, arg: String): String = throw NotImplementedError() - - override fun binaryOperation(operation: String, left: String, right: String): String = when (operation) { - "magic" -> "$left ★ $right" - else -> throw NotImplementedError() + override fun unaryOperation(operation: String): (arg: String) -> String { + throw NotImplementedError() } + + override fun binaryOperation(operation: String): (left: String, right: String) -> String = + when (operation) { + "magic" -> { left, right -> "$left ★ $right" } + else -> throw NotImplementedError() + } } val mst = "magic(a, b)".parseMath() diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index 0630e8e4b..e2413dea8 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -7,9 +7,8 @@ import kscience.kmath.operations.* * * @param algebra The algebra to provide for Expressions built. */ -public abstract class FunctionalExpressionAlgebra>( - public val algebra: A, -) : ExpressionAlgebra> { +public abstract class FunctionalExpressionAlgebra>(public val algebra: A) : + ExpressionAlgebra> { /** * Builds an Expression of constant expression which does not depend on arguments. */ @@ -25,19 +24,18 @@ public abstract class FunctionalExpressionAlgebra>( /** * Builds an Expression of dynamic call of binary operation [operation] on [left] and [right]. */ - public override fun binaryOperation( - operation: String, - left: Expression, - right: Expression, - ): Expression = Expression { arguments -> - algebra.binaryOperation(operation, left.invoke(arguments), right.invoke(arguments)) - } + public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = + { left, right -> + Expression { arguments -> + algebra.binaryOperation(operation)(left.invoke(arguments), right.invoke(arguments)) + } + } /** * Builds an Expression of dynamic call of unary operation with name [operation] on [arg]. */ - public override fun unaryOperation(operation: String, arg: Expression): Expression = Expression { arguments -> - algebra.unaryOperation(operation, arg.invoke(arguments)) + public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = { arg -> + Expression { arguments -> algebra.unaryOperation(operation)(arg.invoke(arguments)) } } } @@ -52,7 +50,7 @@ public open class FunctionalExpressionSpace>(algebra: A) : * Builds an Expression of addition of two another expressions. */ public override fun add(a: Expression, b: Expression): Expression = - binaryOperation(SpaceOperations.PLUS_OPERATION, a, b) + binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) /** * Builds an Expression of multiplication of expression by number. @@ -66,11 +64,11 @@ public open class FunctionalExpressionSpace>(algebra: A) : public operator fun T.plus(arg: Expression): Expression = arg + this public operator fun T.minus(arg: Expression): Expression = arg - this - public override fun unaryOperation(operation: String, arg: Expression): Expression = - super.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = + super.unaryOperation(operation) - public override fun binaryOperation(operation: String, left: Expression, right: Expression): Expression = - super.binaryOperation(operation, left, right) + public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperation(operation) } public open class FunctionalExpressionRing(algebra: A) : FunctionalExpressionSpace(algebra), @@ -82,16 +80,16 @@ public open class FunctionalExpressionRing(algebra: A) : FunctionalExpress * Builds an Expression of multiplication of two expressions. */ public override fun multiply(a: Expression, b: Expression): Expression = - binaryOperation(RingOperations.TIMES_OPERATION, a, b) + binaryOperation(RingOperations.TIMES_OPERATION)(a, b) public operator fun Expression.times(arg: T): Expression = this * const(arg) public operator fun T.times(arg: Expression): Expression = arg * this - public override fun unaryOperation(operation: String, arg: Expression): Expression = - super.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = + super.unaryOperation(operation) - public override fun binaryOperation(operation: String, left: Expression, right: Expression): Expression = - super.binaryOperation(operation, left, right) + public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperation(operation) } public open class FunctionalExpressionField(algebra: A) : @@ -101,49 +99,49 @@ public open class FunctionalExpressionField(algebra: A) : * Builds an Expression of division an expression by another one. */ public override fun divide(a: Expression, b: Expression): Expression = - binaryOperation(FieldOperations.DIV_OPERATION, a, b) + binaryOperation(FieldOperations.DIV_OPERATION)(a, b) public operator fun Expression.div(arg: T): Expression = this / const(arg) public operator fun T.div(arg: Expression): Expression = arg / this - public override fun unaryOperation(operation: String, arg: Expression): Expression = - super.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = + super.unaryOperation(operation) - public override fun binaryOperation(operation: String, left: Expression, right: Expression): Expression = - super.binaryOperation(operation, left, right) + public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperation(operation) } public open class FunctionalExpressionExtendedField(algebra: A) : FunctionalExpressionField(algebra), ExtendedField> where A : ExtendedField, A : NumericAlgebra { public override fun sin(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) + unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) public override fun cos(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.COS_OPERATION, arg) + unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) public override fun asin(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg) + unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) public override fun acos(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg) + unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) public override fun atan(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg) + unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) public override fun power(arg: Expression, pow: Number): Expression = - binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow)) + binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) public override fun exp(arg: Expression): Expression = - unaryOperation(ExponentialOperations.EXP_OPERATION, arg) + unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) - public override fun ln(arg: Expression): Expression = unaryOperation(ExponentialOperations.LN_OPERATION, arg) + public override fun ln(arg: Expression): Expression = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) - public override fun unaryOperation(operation: String, arg: Expression): Expression = - super.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = + super.unaryOperation(operation) - public override fun binaryOperation(operation: String, left: Expression, right: Expression): Expression = - super.binaryOperation(operation, left, right) + public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperation(operation) } public inline fun > A.expressionInSpace(block: FunctionalExpressionSpace.() -> Expression): Expression = diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt index f4dbce89a..174f62c12 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt @@ -18,10 +18,11 @@ public interface MatrixContext : SpaceOperations> { */ public fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): Matrix - public override fun binaryOperation(operation: String, left: Matrix, right: Matrix): Matrix = when (operation) { - "dot" -> left dot right - else -> super.binaryOperation(operation, left, right) - } + public override fun binaryOperation(operation: String): (left: Matrix, right: Matrix) -> Matrix = + when (operation) { + "dot" -> { left, right -> left dot right } + else -> super.binaryOperation(operation) + } /** * Computes the dot product of this matrix and another one. diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index 12a45615a..19ca1a4cc 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -13,19 +13,19 @@ public annotation class KMathContext */ public interface Algebra { /** - * Wrap raw string or variable + * Wraps raw string or variable. */ public fun symbol(value: String): T = error("Wrapping of '$value' is not supported in $this") /** - * Dynamic call of unary operation with name [operation] on [arg] + * Dynamically dispatches an unary operation with name [operation]. */ - public fun unaryOperation(operation: String, arg: T): T + public fun unaryOperation(operation: String): (arg: T) -> T /** - * Dynamic call of binary operation [operation] on [left] and [right] + * Dynamically dispatches a binary operation with name [operation]. */ - public fun binaryOperation(operation: String, left: T, right: T): T + public fun binaryOperation(operation: String): (left: T, right: T) -> T } /** @@ -40,16 +40,28 @@ public interface NumericAlgebra : Algebra { public fun number(value: Number): T /** - * Dynamic call of binary operation [operation] on [left] and [right] where left element is [Number]. + * Dynamically dispatches a binary operation with name [operation] where the left argument is [Number]. */ - public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = - binaryOperation(operation, number(left), right) + public fun leftSideNumberOperation(operation: String): (left: Number, right: T) -> T = + { l, r -> binaryOperation(operation)(number(l), r) } + +// /** +// * Dynamically calls a binary operation with name [operation] where the left argument is [Number]. +// */ +// public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = +// leftSideNumberOperation(operation)(left, right) /** - * Dynamic call of binary operation [operation] on [left] and [right] where right element is [Number]. + * Dynamically dispatches a binary operation with name [operation] where the right argument is [Number]. */ - public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = - leftSideNumberOperation(operation, right, left) + public fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = + { l, r -> binaryOperation(operation)(l, number(r)) } + +// /** +// * Dynamically calls a binary operation with name [operation] where the right argument is [Number]. +// */ +// public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = +// rightSideNumberOperation(operation)(left, right) } /** @@ -146,15 +158,15 @@ public interface SpaceOperations : Algebra { */ public operator fun Number.times(b: T): T = b * this - override fun unaryOperation(operation: String, arg: T): T = when (operation) { - PLUS_OPERATION -> arg - MINUS_OPERATION -> -arg + override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { + PLUS_OPERATION -> { arg -> arg } + MINUS_OPERATION -> { arg -> -arg } else -> error("Unary operation $operation not defined in $this") } - override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) { - PLUS_OPERATION -> add(left, right) - MINUS_OPERATION -> left - right + override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + PLUS_OPERATION -> ::add + MINUS_OPERATION -> { left, right -> left - right } else -> error("Binary operation $operation not defined in $this") } @@ -207,9 +219,9 @@ public interface RingOperations : SpaceOperations { */ public operator fun T.times(b: T): T = multiply(this, b) - override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) { - TIMES_OPERATION -> multiply(left, right) - else -> super.binaryOperation(operation, left, right) + override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + TIMES_OPERATION -> ::multiply + else -> super.binaryOperation(operation) } public companion object { @@ -234,20 +246,6 @@ public interface Ring : Space, RingOperations, NumericAlgebra { override fun number(value: Number): T = one * value.toDouble() - override fun leftSideNumberOperation(operation: String, left: Number, right: T): T = when (operation) { - SpaceOperations.PLUS_OPERATION -> left + right - SpaceOperations.MINUS_OPERATION -> left - right - RingOperations.TIMES_OPERATION -> left * right - else -> super.leftSideNumberOperation(operation, left, right) - } - - override fun rightSideNumberOperation(operation: String, left: T, right: Number): T = when (operation) { - SpaceOperations.PLUS_OPERATION -> left + right - SpaceOperations.MINUS_OPERATION -> left - right - RingOperations.TIMES_OPERATION -> left * right - else -> super.rightSideNumberOperation(operation, left, right) - } - /** * Addition of element and scalar. * @@ -308,9 +306,9 @@ public interface FieldOperations : RingOperations { */ public operator fun T.div(b: T): T = divide(this, b) - override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) { - DIV_OPERATION -> divide(left, right) - else -> super.binaryOperation(operation, left, right) + override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + DIV_OPERATION -> ::divide + else -> super.binaryOperation(operation) } public companion object { diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt index a2b33a0c4..611222d34 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt @@ -15,23 +15,23 @@ public interface ExtendedFieldOperations : public override fun tan(arg: T): T = sin(arg) / cos(arg) public override fun tanh(arg: T): T = sinh(arg) / cosh(arg) - public override fun unaryOperation(operation: String, arg: T): T = when (operation) { - TrigonometricOperations.COS_OPERATION -> cos(arg) - TrigonometricOperations.SIN_OPERATION -> sin(arg) - TrigonometricOperations.TAN_OPERATION -> tan(arg) - TrigonometricOperations.ACOS_OPERATION -> acos(arg) - TrigonometricOperations.ASIN_OPERATION -> asin(arg) - TrigonometricOperations.ATAN_OPERATION -> atan(arg) - HyperbolicOperations.COSH_OPERATION -> cosh(arg) - HyperbolicOperations.SINH_OPERATION -> sinh(arg) - HyperbolicOperations.TANH_OPERATION -> tanh(arg) - HyperbolicOperations.ACOSH_OPERATION -> acosh(arg) - HyperbolicOperations.ASINH_OPERATION -> asinh(arg) - HyperbolicOperations.ATANH_OPERATION -> atanh(arg) - PowerOperations.SQRT_OPERATION -> sqrt(arg) - ExponentialOperations.EXP_OPERATION -> exp(arg) - ExponentialOperations.LN_OPERATION -> ln(arg) - else -> super.unaryOperation(operation, arg) + public override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { + TrigonometricOperations.COS_OPERATION -> ::cos + TrigonometricOperations.SIN_OPERATION -> ::sin + TrigonometricOperations.TAN_OPERATION -> ::tan + TrigonometricOperations.ACOS_OPERATION -> ::acos + TrigonometricOperations.ASIN_OPERATION -> ::asin + TrigonometricOperations.ATAN_OPERATION -> ::atan + HyperbolicOperations.COSH_OPERATION -> ::cosh + HyperbolicOperations.SINH_OPERATION -> ::sinh + HyperbolicOperations.TANH_OPERATION -> ::tanh + HyperbolicOperations.ACOSH_OPERATION -> ::acosh + HyperbolicOperations.ASINH_OPERATION -> ::asinh + HyperbolicOperations.ATANH_OPERATION -> ::atanh + PowerOperations.SQRT_OPERATION -> ::sqrt + ExponentialOperations.EXP_OPERATION -> ::exp + ExponentialOperations.LN_OPERATION -> ::ln + else -> super.unaryOperation(operation) } } @@ -46,10 +46,11 @@ public interface ExtendedField : ExtendedFieldOperations, Field { public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one))) public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2 - public override fun rightSideNumberOperation(operation: String, left: T, right: Number): T = when (operation) { - PowerOperations.POW_OPERATION -> power(left, right) - else -> super.rightSideNumberOperation(operation, left, right) - } + public override fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = + when (operation) { + PowerOperations.POW_OPERATION -> ::power + else -> super.rightSideNumberOperation(operation) + } } /** @@ -80,10 +81,11 @@ public object RealField : ExtendedField, Norm { public override val one: Double get() = 1.0 - public override fun binaryOperation(operation: String, left: Double, right: Double): Double = when (operation) { - PowerOperations.POW_OPERATION -> left pow right - else -> super.binaryOperation(operation, left, right) - } + public override fun binaryOperation(operation: String): (left: Double, right: Double) -> Double = + when (operation) { + PowerOperations.POW_OPERATION -> ::power + else -> super.binaryOperation(operation) + } public override inline fun add(a: Double, b: Double): Double = a + b public override inline fun multiply(a: Double, k: Number): Double = a * k.toDouble() @@ -130,9 +132,9 @@ public object FloatField : ExtendedField, Norm { public override val one: Float get() = 1.0f - public override fun binaryOperation(operation: String, left: Float, right: Float): Float = when (operation) { - PowerOperations.POW_OPERATION -> left pow right - else -> super.binaryOperation(operation, left, right) + public override fun binaryOperation(operation: String): (left: Float, right: Float) -> Float = when (operation) { + PowerOperations.POW_OPERATION -> ::power + else -> super.binaryOperation(operation) } public override inline fun add(a: Float, b: Float): Float = a + b From e447a15304f2c1b7df9ad00c48a721db9f92edc6 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sat, 28 Nov 2020 13:42:18 +0700 Subject: [PATCH 02/39] Make MstAlgebra operations return specific types --- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 101 +++++++++--------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index cea708342..44a7f20b9 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -7,10 +7,10 @@ import kscience.kmath.operations.* */ public object MstAlgebra : NumericAlgebra { public override fun number(value: Number): MST.Numeric = MST.Numeric(value) - public override fun symbol(value: String): MST.Symbolic = MST.Symbolic(value) - public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = { arg -> MST.Unary(operation, arg) } + public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = + { arg -> MST.Unary(operation, arg) } public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = { left, right -> MST.Binary(operation, left, right) } @@ -25,92 +25,95 @@ public object MstSpace : Space, NumericAlgebra { public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) - override fun multiply(a: MST, k: Number): MST = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) + override fun multiply(a: MST, k: Number): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) - override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstAlgebra.binaryOperation(operation) - override fun unaryOperation(operation: String): (arg: MST) -> MST = MstAlgebra.unaryOperation(operation) + override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstAlgebra.unaryOperation(operation) } /** * [Ring] over [MST] nodes. */ public object MstRing : Ring, NumericAlgebra { - override val zero: MST + override val zero: MST.Numeric get() = MstSpace.zero - override val one: MST = number(1.0) - public override fun number(value: Number): MST = MstSpace.number(value) - public override fun symbol(value: String): MST = MstSpace.symbol(value) - public override fun add(a: MST, b: MST): MST = MstSpace.add(a, b) - public override fun multiply(a: MST, k: Number): MST = MstSpace.multiply(a, k) - public override fun multiply(a: MST, b: MST): MST = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) + override val one: MST.Numeric by lazy { number(1.0) } - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + public override fun number(value: Number): MST.Numeric = MstSpace.number(value) + public override fun symbol(value: String): MST.Symbolic = MstSpace.symbol(value) + public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) + public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) + public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) + + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstSpace.binaryOperation(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST = MstAlgebra.unaryOperation(operation) + public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = + MstAlgebra.unaryOperation(operation) } /** * [Field] over [MST] nodes. */ public object MstField : Field { - public override val zero: MST + public override val zero: MST.Numeric get() = MstRing.zero - public override val one: MST + public override val one: MST.Numeric get() = MstRing.one - public override fun symbol(value: String): MST = MstRing.symbol(value) - public override fun number(value: Number): MST = MstRing.number(value) - public override fun add(a: MST, b: MST): MST = MstRing.add(a, b) - public override fun multiply(a: MST, k: Number): MST = MstRing.multiply(a, k) - public override fun multiply(a: MST, b: MST): MST = MstRing.multiply(a, b) - public override fun divide(a: MST, b: MST): MST = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) + public override fun symbol(value: String): MST.Symbolic = MstRing.symbol(value) + public override fun number(value: Number): MST.Numeric = MstRing.number(value) + public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b) + public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) + public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) + public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstRing.binaryOperation(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST = MstRing.unaryOperation(operation) + public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstRing.unaryOperation(operation) } /** * [ExtendedField] over [MST] nodes. */ public object MstExtendedField : ExtendedField { - public override val zero: MST + public override val zero: MST.Numeric get() = MstField.zero - public override val one: MST + public override val one: MST.Numeric get() = MstField.one public override fun symbol(value: String): MST = MstField.symbol(value) - public override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) - public override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) - public override fun tan(arg: MST): MST = unaryOperation(TrigonometricOperations.TAN_OPERATION)(arg) - public override fun asin(arg: MST): MST = unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) - public override fun acos(arg: MST): MST = unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) - public override fun atan(arg: MST): MST = unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) - public override fun sinh(arg: MST): MST = unaryOperation(HyperbolicOperations.SINH_OPERATION)(arg) - public override fun cosh(arg: MST): MST = unaryOperation(HyperbolicOperations.COSH_OPERATION)(arg) - public override fun tanh(arg: MST): MST = unaryOperation(HyperbolicOperations.TANH_OPERATION)(arg) - public override fun asinh(arg: MST): MST = unaryOperation(HyperbolicOperations.ASINH_OPERATION)(arg) - public override fun acosh(arg: MST): MST = unaryOperation(HyperbolicOperations.ACOSH_OPERATION)(arg) - public override fun atanh(arg: MST): MST = unaryOperation(HyperbolicOperations.ATANH_OPERATION)(arg) - public override fun add(a: MST, b: MST): MST = MstField.add(a, b) - public override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k) - public override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b) - public override fun divide(a: MST, b: MST): MST = MstField.divide(a, b) - public override fun power(arg: MST, pow: Number): MST = binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) - public override fun exp(arg: MST): MST = unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) - public override fun ln(arg: MST): MST = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) + public override fun sin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) + public override fun cos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) + public override fun tan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.TAN_OPERATION)(arg) + public override fun asin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) + public override fun acos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) + public override fun atan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) + public override fun sinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.SINH_OPERATION)(arg) + public override fun cosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.COSH_OPERATION)(arg) + public override fun tanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.TANH_OPERATION)(arg) + public override fun asinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ASINH_OPERATION)(arg) + public override fun acosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ACOSH_OPERATION)(arg) + public override fun atanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ATANH_OPERATION)(arg) + public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b) + public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) + public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) + public override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b) - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST = + public override fun power(arg: MST, pow: Number): MST.Binary = + binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) + + public override fun exp(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) + public override fun ln(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) + + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstField.binaryOperation(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST = MstField.unaryOperation(operation) - override fun unaryOperation(operation: String, arg: MST): MST.Unary = - MST.Unary(operation, arg) + public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstField.unaryOperation(operation) } From e62cf4fc6586643f6a5adddd2e1f25deb1b756cc Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 8 Dec 2020 14:42:42 +0700 Subject: [PATCH 03/39] Rewrite ASM codegen to use curried operators, fix bugs, update benchmarks --- .../ast/ExpressionsInterpretersBenchmark.kt | 49 +-- .../kmath/structures/ArrayBenchmark.kt | 8 +- .../kmath/structures/ViktorBenchmark.kt | 2 +- .../kotlin/kscience/kmath/ast/MST.kt | 3 +- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 15 +- .../kscience/kmath/ast/MstExpression.kt | 7 +- .../jvmMain/kotlin/kscience/kmath/asm/asm.kt | 49 +-- .../kscience/kmath/asm/internal/AsmBuilder.kt | 300 ++++-------------- .../kscience/kmath/asm/internal/MstType.kt | 20 -- .../kmath/asm/internal/codegenUtils.kt | 120 ------- .../kscience/kmath/asm/TestAsmAlgebras.kt | 36 +-- .../kscience/kmath/asm/TestAsmExpressions.kt | 12 +- .../kmath/asm/TestAsmSpecialization.kt | 2 +- .../kscience/kmath/asm/TestAsmVariables.kt | 2 +- .../kscience/kmath/operations/Algebra.kt | 10 +- .../kmath/operations/NumberAlgebra.kt | 2 +- 16 files changed, 158 insertions(+), 479 deletions(-) rename examples/src/{main => benchmarks}/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt (66%) delete mode 100644 kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt diff --git a/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt similarity index 66% rename from examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt rename to examples/src/benchmarks/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt index a4806ed68..6acaca84d 100644 --- a/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt @@ -4,13 +4,19 @@ import kscience.kmath.asm.compile import kscience.kmath.expressions.Expression import kscience.kmath.expressions.expressionInField import kscience.kmath.expressions.invoke +import kscience.kmath.expressions.symbol import kscience.kmath.operations.Field import kscience.kmath.operations.RealField +import org.openjdk.jmh.annotations.Benchmark +import org.openjdk.jmh.annotations.Scope +import org.openjdk.jmh.annotations.State import kotlin.random.Random -import kotlin.system.measureTimeMillis +@State(Scope.Benchmark) internal class ExpressionsInterpretersBenchmark { private val algebra: Field = RealField + + @Benchmark fun functionalExpression() { val expr = algebra.expressionInField { symbol("x") * const(2.0) + const(2.0) / symbol("x") - const(16.0) @@ -19,6 +25,7 @@ internal class ExpressionsInterpretersBenchmark { invokeAndSum(expr) } + @Benchmark fun mstExpression() { val expr = algebra.mstInField { symbol("x") * number(2.0) + number(2.0) / symbol("x") - number(16.0) @@ -27,6 +34,7 @@ internal class ExpressionsInterpretersBenchmark { invokeAndSum(expr) } + @Benchmark fun asmExpression() { val expr = algebra.mstInField { symbol("x") * number(2.0) + number(2.0) / symbol("x") - number(16.0) @@ -35,6 +43,13 @@ internal class ExpressionsInterpretersBenchmark { invokeAndSum(expr) } + @Benchmark + fun rawExpression() { + val x by symbol + val expr = Expression { args -> args.getValue(x) * 2.0 + 2.0 / args.getValue(x) - 16.0 } + invokeAndSum(expr) + } + private fun invokeAndSum(expr: Expression) { val random = Random(0) var sum = 0.0 @@ -46,35 +61,3 @@ internal class ExpressionsInterpretersBenchmark { println(sum) } } - -/** - * This benchmark compares basically evaluation of simple function with MstExpression interpreter, ASM backend and - * core FunctionalExpressions API. - * - * The expected rating is: - * - * 1. ASM. - * 2. MST. - * 3. FE. - */ -fun main() { - val benchmark = ExpressionsInterpretersBenchmark() - - val fe = measureTimeMillis { - benchmark.functionalExpression() - } - - println("fe=$fe") - - val mst = measureTimeMillis { - benchmark.mstExpression() - } - - println("mst=$mst") - - val asm = measureTimeMillis { - benchmark.asmExpression() - } - - println("asm=$asm") -} diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt index a91d02253..f7e0d05c6 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt @@ -16,17 +16,13 @@ internal class ArrayBenchmark { @Benchmark fun benchmarkBufferRead() { var res = 0 - for (i in 1..size) res += arrayBuffer.get( - size - i - ) + for (i in 1..size) res += arrayBuffer[size - i] } @Benchmark fun nativeBufferRead() { var res = 0 - for (i in 1..size) res += nativeBuffer.get( - size - i - ) + for (i in 1..size) res += nativeBuffer[size - i] } companion object { diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt index 464925ca0..df35b0b78 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt @@ -36,7 +36,7 @@ internal class ViktorBenchmark { @Benchmark fun rawViktor() { - val one = F64Array.full(init = 1.0, shape = *intArrayOf(dim, dim)) + val one = F64Array.full(init = 1.0, shape = intArrayOf(dim, dim)) var res = one repeat(n) { res = res + one } } diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt index cc3d38f9c..4ff4d7354 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt @@ -64,7 +64,8 @@ public fun Algebra.evaluate(node: MST): T = when (node) { node.left is MST.Numeric && node.right is MST.Numeric -> { val number = RealField - .binaryOperation(node.operation)(node.left.value.toDouble(), node.right.value.toDouble()) + .binaryOperation(node.operation) + .invoke(node.left.value.toDouble(), node.right.value.toDouble()) number(number) } diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index 44a7f20b9..96703ffb8 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -24,13 +24,17 @@ public object MstSpace : Space, NumericAlgebra { public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) - override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) - override fun multiply(a: MST, k: Number): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) + public override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) + public override fun MST.unaryMinus(): MST = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) - override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = + public override fun multiply(a: MST, k: Number): MST.Binary = + binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) + + public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstAlgebra.binaryOperation(operation) - override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstAlgebra.unaryOperation(operation) + public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = + MstAlgebra.unaryOperation(operation) } /** @@ -47,6 +51,7 @@ public object MstRing : Ring, NumericAlgebra { public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) + public override fun MST.unaryMinus(): MST = MstSpace.unaryOperation(SpaceOperations.MINUS_OPERATION)(this) public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstSpace.binaryOperation(operation) @@ -71,6 +76,7 @@ public object MstField : Field { public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) + public override fun MST.unaryMinus(): MST = MstSpace.unaryOperation(SpaceOperations.MINUS_OPERATION)(this) public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstRing.binaryOperation(operation) @@ -105,6 +111,7 @@ public object MstExtendedField : ExtendedField { public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) public override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b) + public override fun MST.unaryMinus(): MST = MstSpace.unaryOperation(SpaceOperations.MINUS_OPERATION)(this) public override fun power(arg: MST, pow: Number): MST.Binary = binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt index 8a99fd2f4..4d1b65621 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt @@ -15,7 +15,12 @@ import kotlin.contracts.contract */ public class MstExpression>(public val algebra: A, public val mst: MST) : Expression { private inner class InnerAlgebra(val arguments: Map) : NumericAlgebra { - override fun symbol(value: String): T = arguments[StringSymbol(value)] ?: algebra.symbol(value) + override fun symbol(value: String): T = try { + algebra.symbol(value) + } catch (ignored: IllegalStateException) { + null + } ?: arguments.getValue(StringSymbol(value)) + override fun unaryOperation(operation: String): (arg: T) -> T = algebra.unaryOperation(operation) override fun binaryOperation(operation: String): (left: T, right: T) -> T = algebra.binaryOperation(operation) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt index 9ccfa464c..932813182 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt @@ -1,13 +1,13 @@ package kscience.kmath.asm import kscience.kmath.asm.internal.AsmBuilder -import kscience.kmath.asm.internal.MstType -import kscience.kmath.asm.internal.buildAlgebraOperationCall import kscience.kmath.asm.internal.buildName import kscience.kmath.ast.MST import kscience.kmath.ast.MstExpression import kscience.kmath.expressions.Expression import kscience.kmath.operations.Algebra +import kscience.kmath.operations.NumericAlgebra +import kscience.kmath.operations.RealField /** * Compiles given MST to an Expression using AST compiler. @@ -23,37 +23,46 @@ internal fun MST.compileWith(type: Class, algebra: Algebra): Exp is MST.Symbolic -> { val symbol = try { algebra.symbol(node.value) - } catch (ignored: Throwable) { + } catch (ignored: IllegalStateException) { null } if (symbol != null) - loadTConstant(symbol) + loadObjectConstant(symbol as Any) else loadVariable(node.value) } - is MST.Numeric -> loadNumeric(node.value) + is MST.Numeric -> loadNumberConstant(node.value) + is MST.Unary -> buildCall(algebra.unaryOperation(node.operation)) { visit(node.value) } - is MST.Unary -> buildAlgebraOperationCall( - context = algebra, - name = node.operation, - fallbackMethodName = "unaryOperation", - parameterTypes = arrayOf(MstType.fromMst(node.value)) - ) { visit(node.value) } + is MST.Binary -> when { + algebra is NumericAlgebra && node.left is MST.Numeric && node.right is MST.Numeric -> loadObjectConstant( + algebra.number( + RealField + .binaryOperation(node.operation) + .invoke(node.left.value.toDouble(), node.right.value.toDouble()) + ) + ) - is MST.Binary -> buildAlgebraOperationCall( - context = algebra, - name = node.operation, - fallbackMethodName = "binaryOperation", - parameterTypes = arrayOf(MstType.fromMst(node.left), MstType.fromMst(node.right)) - ) { - visit(node.left) - visit(node.right) + algebra is NumericAlgebra && node.left is MST.Numeric -> buildCall(algebra.leftSideNumberOperation(node.operation)) { + visit(node.left) + visit(node.right) + } + + algebra is NumericAlgebra && node.right is MST.Numeric -> buildCall(algebra.rightSideNumberOperation(node.operation)) { + visit(node.left) + visit(node.right) + } + + else -> buildCall(algebra.binaryOperation(node.operation)) { + visit(node.left) + visit(node.right) + } } } - return AsmBuilder(type, algebra, buildName(this)) { visit(this@compileWith) }.getInstance() + return AsmBuilder(type, buildName(this)) { visit(this@compileWith) }.instance } /** diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index a1e482103..792034232 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -4,26 +4,24 @@ import kscience.kmath.asm.internal.AsmBuilder.ClassLoader import kscience.kmath.ast.MST import kscience.kmath.expressions.Expression import kscience.kmath.operations.Algebra -import kscience.kmath.operations.NumericAlgebra import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* import org.objectweb.asm.commons.InstructionAdapter -import java.util.* -import java.util.stream.Collectors +import java.util.stream.Collectors.toMap +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract /** * ASM Builder is a structure that abstracts building a class designated to unwrap [MST] to plain Java expression. * This class uses [ClassLoader] for loading the generated class, then it is able to instantiate the new class. * * @property T the type of AsmExpression to unwrap. - * @property algebra the algebra the applied AsmExpressions use. * @property className the unique class name of new loaded class. * @property invokeLabel0Visitor the function to apply to this object when generating invoke method, label 0. * @author Iaroslav Postovalov */ internal class AsmBuilder internal constructor( - private val classOfT: Class<*>, - private val algebra: Algebra, + classOfT: Class<*>, private val className: String, private val invokeLabel0Visitor: AsmBuilder.() -> Unit, ) { @@ -39,15 +37,10 @@ internal class AsmBuilder internal constructor( */ private val classLoader: ClassLoader = ClassLoader(javaClass.classLoader) - /** - * ASM Type for [algebra]. - */ - private val tAlgebraType: Type = algebra.javaClass.asm - /** * ASM type for [T]. */ - internal val tType: Type = classOfT.asm + private val tType: Type = classOfT.asm /** * ASM type for new class. @@ -69,51 +62,13 @@ internal class AsmBuilder internal constructor( */ private var hasConstants: Boolean = true - /** - * States whether [T] a primitive type, so [AsmBuilder] may generate direct primitive calls. - */ - internal var primitiveMode: Boolean = false - - /** - * Primitive type to apply for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode]. - */ - internal var primitiveMask: Type = OBJECT_TYPE - - /** - * Boxed primitive type to apply for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode]. - */ - internal var primitiveMaskBoxed: Type = OBJECT_TYPE - - /** - * Stack of useful objects types on stack to verify types. - */ - private val typeStack: ArrayDeque = ArrayDeque() - - /** - * Stack of useful objects types on stack expected by algebra calls. - */ - internal val expectationStack: ArrayDeque = ArrayDeque(1).also { it.push(tType) } - - /** - * The cache for instance built by this builder. - */ - private var generatedInstance: Expression? = null - /** * Subclasses, loads and instantiates [Expression] for given parameters. * * The built instance is cached. */ @Suppress("UNCHECKED_CAST") - internal fun getInstance(): Expression { - generatedInstance?.let { return it } - - if (SIGNATURE_LETTERS.containsKey(classOfT)) { - primitiveMode = true - primitiveMask = SIGNATURE_LETTERS.getValue(classOfT) - primitiveMaskBoxed = tType - } - + val instance: Expression by lazy { val classWriter = ClassWriter(ClassWriter.COMPUTE_FRAMES) { visit( V1_8, @@ -192,15 +147,6 @@ internal class AsmBuilder internal constructor( hasConstants = constants.isNotEmpty() - visitField( - access = ACC_PRIVATE or ACC_FINAL, - name = "algebra", - descriptor = tAlgebraType.descriptor, - signature = null, - value = null, - block = FieldVisitor::visitEnd - ) - if (hasConstants) visitField( access = ACC_PRIVATE or ACC_FINAL, @@ -214,25 +160,17 @@ internal class AsmBuilder internal constructor( visitMethod( ACC_PUBLIC, "", - - Type.getMethodDescriptor( - Type.VOID_TYPE, - tAlgebraType, - *OBJECT_ARRAY_TYPE.wrapToArrayIf { hasConstants }), - + Type.getMethodDescriptor(Type.VOID_TYPE, *OBJECT_ARRAY_TYPE.wrapToArrayIf { hasConstants }), null, null ).instructionAdapter { val thisVar = 0 - val algebraVar = 1 - val constantsVar = 2 + val constantsVar = 1 val l0 = label() load(thisVar, classType) invokespecial(OBJECT_TYPE.internalName, "", Type.getMethodDescriptor(Type.VOID_TYPE), false) label() load(thisVar, classType) - load(algebraVar, tAlgebraType) - putfield(classType.internalName, "algebra", tAlgebraType.descriptor) if (hasConstants) { label() @@ -246,15 +184,6 @@ internal class AsmBuilder internal constructor( val l4 = label() visitLocalVariable("this", classType.descriptor, null, l0, l4, thisVar) - visitLocalVariable( - "algebra", - tAlgebraType.descriptor, - null, - l0, - l4, - algebraVar - ) - if (hasConstants) visitLocalVariable("constants", OBJECT_ARRAY_TYPE.descriptor, null, l0, l4, constantsVar) @@ -265,33 +194,55 @@ internal class AsmBuilder internal constructor( visitEnd() } - val new = classLoader +// java.io.File("dump.class").writeBytes(classWriter.toByteArray()) + + classLoader .defineClass(className, classWriter.toByteArray()) .constructors .first() - .newInstance(algebra, *(constants.toTypedArray().wrapToArrayIf { hasConstants })) as Expression - - generatedInstance = new - return new + .newInstance(*(constants.toTypedArray().wrapToArrayIf { hasConstants })) as Expression } /** - * Loads a [T] constant from [constants]. + * Loads [java.lang.Object] constant from constants. */ - internal fun loadTConstant(value: T) { - if (classOfT in INLINABLE_NUMBERS) { - val expectedType = expectationStack.pop() - val mustBeBoxed = expectedType.sort == Type.OBJECT - loadNumberConstant(value as Number, mustBeBoxed) + fun loadObjectConstant(value: Any, type: Type = tType): Unit = invokeMethodVisitor.run { + val idx = if (value in constants) constants.indexOf(value) else constants.also { it += value }.lastIndex + loadThis() + getfield(classType.internalName, "constants", OBJECT_ARRAY_TYPE.descriptor) + iconst(idx) + visitInsn(AALOAD) + checkcast(type) + } - if (mustBeBoxed) - invokeMethodVisitor.checkcast(tType) + /** + * Loads `this` variable. + */ + private fun loadThis(): Unit = invokeMethodVisitor.load(invokeThisVar, classType) - if (mustBeBoxed) typeStack.push(tType) else typeStack.push(primitiveMask) + /** + * Either loads a numeric constant [value] from the class's constants field or boxes a primitive + * constant from the constant pool. + */ + fun loadNumberConstant(value: Number) { + val boxed = value.javaClass.asm + val primitive = BOXED_TO_PRIMITIVES[boxed] + + if (primitive != null) { + when (primitive) { + Type.BYTE_TYPE -> invokeMethodVisitor.iconst(value.toInt()) + Type.DOUBLE_TYPE -> invokeMethodVisitor.dconst(value.toDouble()) + Type.FLOAT_TYPE -> invokeMethodVisitor.fconst(value.toFloat()) + Type.LONG_TYPE -> invokeMethodVisitor.lconst(value.toLong()) + Type.INT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) + Type.SHORT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) + } + + box(primitive) return } - loadObjectConstant(value as Any, tType) + loadObjectConstant(value, boxed) } /** @@ -309,77 +260,9 @@ internal class AsmBuilder internal constructor( } /** - * Unboxes the current boxed value and pushes it. + * Loads a variable [name] from arguments [Map] parameter of [Expression.invoke]. */ - private fun unboxTo(primitive: Type) = invokeMethodVisitor.invokevirtual( - NUMBER_TYPE.internalName, - NUMBER_CONVERTER_METHODS.getValue(primitive), - Type.getMethodDescriptor(primitive), - false - ) - - /** - * Loads [java.lang.Object] constant from constants. - */ - private fun loadObjectConstant(value: Any, type: Type): Unit = invokeMethodVisitor.run { - val idx = if (value in constants) constants.indexOf(value) else constants.apply { add(value) }.lastIndex - loadThis() - getfield(classType.internalName, "constants", OBJECT_ARRAY_TYPE.descriptor) - iconst(idx) - visitInsn(AALOAD) - checkcast(type) - } - - internal fun loadNumeric(value: Number) { - if (expectationStack.peek() == NUMBER_TYPE) { - loadNumberConstant(value, true) - expectationStack.pop() - typeStack.push(NUMBER_TYPE) - } else (algebra as? NumericAlgebra)?.number(value)?.let { loadTConstant(it) } - ?: error("Cannot resolve numeric $value since target algebra is not numeric, and the current operation doesn't accept numbers.") - } - - /** - * Loads this variable. - */ - private fun loadThis(): Unit = invokeMethodVisitor.load(invokeThisVar, classType) - - /** - * Either loads a numeric constant [value] from the class's constants field or boxes a primitive - * constant from the constant pool (some numbers with special opcodes like [Opcodes.ICONST_0] aren't even loaded - * from it). - */ - private fun loadNumberConstant(value: Number, mustBeBoxed: Boolean) { - val boxed = value.javaClass.asm - val primitive = BOXED_TO_PRIMITIVES[boxed] - - if (primitive != null) { - when (primitive) { - Type.BYTE_TYPE -> invokeMethodVisitor.iconst(value.toInt()) - Type.DOUBLE_TYPE -> invokeMethodVisitor.dconst(value.toDouble()) - Type.FLOAT_TYPE -> invokeMethodVisitor.fconst(value.toFloat()) - Type.LONG_TYPE -> invokeMethodVisitor.lconst(value.toLong()) - Type.INT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) - Type.SHORT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) - } - - if (mustBeBoxed) - box(primitive) - - return - } - - loadObjectConstant(value, boxed) - - if (!mustBeBoxed) - unboxTo(primitiveMask) - } - - /** - * Loads a variable [name] from arguments [Map] parameter of [Expression.invoke]. The [defaultValue] may be - * provided. - */ - internal fun loadVariable(name: String): Unit = invokeMethodVisitor.run { + fun loadVariable(name: String): Unit = invokeMethodVisitor.run { load(invokeArgumentsVar, MAP_TYPE) aconst(name) @@ -391,70 +274,28 @@ internal class AsmBuilder internal constructor( ) checkcast(tType) - val expectedType = expectationStack.pop() - - if (expectedType.sort == Type.OBJECT) - typeStack.push(tType) - else { - unboxTo(primitiveMask) - typeStack.push(primitiveMask) - } } - /** - * Loads algebra from according field of the class and casts it to class of [algebra] provided. - */ - internal fun loadAlgebra() { - loadThis() - invokeMethodVisitor.getfield(classType.internalName, "algebra", tAlgebraType.descriptor) - } + inline fun buildCall(function: Function, parameters: AsmBuilder.() -> Unit) { + contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) } + val `interface` = function.javaClass.interfaces.first { it.interfaces.contains(Function::class.java) } - /** - * Writes a method instruction of opcode with its [owner], [method] and its [descriptor]. The default opcode is - * [Opcodes.INVOKEINTERFACE], since most Algebra functions are declared in interfaces. [loadAlgebra] should be - * called before the arguments and this operation. - * - * The result is casted to [T] automatically. - */ - internal fun invokeAlgebraOperation( - owner: String, - method: String, - descriptor: String, - expectedArity: Int, - opcode: Int = INVOKEINTERFACE, - ) { - run loop@{ - repeat(expectedArity) { - if (typeStack.isEmpty()) return@loop - typeStack.pop() - } - } + val arity = `interface`.methods.find { it.name == "invoke" }?.parameterCount + ?: error("Provided function object doesn't contain invoke method") - invokeMethodVisitor.visitMethodInsn( - opcode, - owner, - method, - descriptor, - opcode == INVOKEINTERFACE + val type = Type.getType(`interface`) + loadObjectConstant(function, type) + parameters(this) + + invokeMethodVisitor.invokeinterface( + type.internalName, + "invoke", + Type.getMethodDescriptor(OBJECT_TYPE, *Array(arity) { OBJECT_TYPE}), ) invokeMethodVisitor.checkcast(tType) - val isLastExpr = expectationStack.size == 1 - val expectedType = expectationStack.pop() - - if (expectedType.sort == Type.OBJECT || isLastExpr) - typeStack.push(tType) - else { - unboxTo(primitiveMask) - typeStack.push(primitiveMask) - } } - /** - * Writes a LDC Instruction with string constant provided. - */ - internal fun loadStringConstant(string: String): Unit = invokeMethodVisitor.aconst(string) - internal companion object { /** * Index of `this` variable in invoke method of the built subclass. @@ -490,32 +331,13 @@ internal class AsmBuilder internal constructor( */ private val PRIMITIVES_TO_BOXED: Map by lazy { BOXED_TO_PRIMITIVES.entries.stream().collect( - Collectors.toMap( + toMap( Map.Entry::value, Map.Entry::key ) ) } - /** - * Maps primitive ASM types to [Number] functions unboxing them. - */ - private val NUMBER_CONVERTER_METHODS: Map by lazy { - hashMapOf( - Type.BYTE_TYPE to "byteValue", - Type.SHORT_TYPE to "shortValue", - Type.INT_TYPE to "intValue", - Type.LONG_TYPE to "longValue", - Type.FLOAT_TYPE to "floatValue", - Type.DOUBLE_TYPE to "doubleValue" - ) - } - - /** - * Provides boxed number types values of which can be stored in JVM bytecode constant pool. - */ - private val INLINABLE_NUMBERS: Set> by lazy { SIGNATURE_LETTERS.keys } - /** * ASM type for [Expression]. */ diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt deleted file mode 100644 index 526c27305..000000000 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt +++ /dev/null @@ -1,20 +0,0 @@ -package kscience.kmath.asm.internal - -import kscience.kmath.ast.MST - -/** - * Represents types known in [MST], numbers and general values. - */ -internal enum class MstType { - GENERAL, - NUMBER; - - companion object { - fun fromMst(mst: MST): MstType { - if (mst is MST.Numeric) - return NUMBER - - return GENERAL - } - } -} diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt index ef9751502..d301ddf15 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt @@ -2,29 +2,11 @@ package kscience.kmath.asm.internal import kscience.kmath.ast.MST import kscience.kmath.expressions.Expression -import kscience.kmath.operations.Algebra -import kscience.kmath.operations.FieldOperations -import kscience.kmath.operations.RingOperations -import kscience.kmath.operations.SpaceOperations import org.objectweb.asm.* -import org.objectweb.asm.Opcodes.INVOKEVIRTUAL import org.objectweb.asm.commons.InstructionAdapter -import java.lang.reflect.Method -import java.util.* import kotlin.contracts.InvocationKind import kotlin.contracts.contract -private val methodNameAdapters: Map, String> by lazy { - hashMapOf( - SpaceOperations.PLUS_OPERATION to 2 to "add", - RingOperations.TIMES_OPERATION to 2 to "multiply", - FieldOperations.DIV_OPERATION to 2 to "divide", - SpaceOperations.PLUS_OPERATION to 1 to "unaryPlus", - SpaceOperations.MINUS_OPERATION to 1 to "unaryMinus", - SpaceOperations.MINUS_OPERATION to 2 to "minus" - ) -} - /** * Returns ASM [Type] for given [Class]. * @@ -110,106 +92,4 @@ internal inline fun ClassWriter.visitField( return visitField(access, name, descriptor, signature, value).apply(block) } -private fun AsmBuilder.findSpecific(context: Algebra, name: String, parameterTypes: Array): Method? = - context.javaClass.methods.find { method -> - val nameValid = method.name == name - val arityValid = method.parameters.size == parameterTypes.size - val notBridgeInPrimitive = !(primitiveMode && method.isBridge) - val paramsValid = method.parameterTypes.zip(parameterTypes).all { (type, mstType) -> - !(mstType != MstType.NUMBER && type == java.lang.Number::class.java) - } - - nameValid && arityValid && notBridgeInPrimitive && paramsValid - } - -/** - * Checks if the target [context] for code generation contains a method with needed [name] and arity, also builds - * type expectation stack for needed arity. - * - * @author Iaroslav Postovalov - */ -private fun AsmBuilder.buildExpectationStack( - context: Algebra, - name: String, - parameterTypes: Array -): Boolean { - val arity = parameterTypes.size - val specific = findSpecific(context, methodNameAdapters[name to arity] ?: name, parameterTypes) - - if (specific != null) - mapTypes(specific, parameterTypes).reversed().forEach { expectationStack.push(it) } - else - expectationStack.addAll(Collections.nCopies(arity, tType)) - - return specific != null -} - -private fun AsmBuilder.mapTypes(method: Method, parameterTypes: Array): List = method - .parameterTypes - .zip(parameterTypes) - .map { (type, mstType) -> - when { - type == java.lang.Number::class.java && mstType == MstType.NUMBER -> AsmBuilder.NUMBER_TYPE - else -> if (primitiveMode) primitiveMask else primitiveMaskBoxed - } - } - -/** - * Checks if the target [context] for code generation contains a method with needed [name] and arity and inserts - * [AsmBuilder.invokeAlgebraOperation] of this method. - * - * @author Iaroslav Postovalov - */ -private fun AsmBuilder.tryInvokeSpecific( - context: Algebra, - name: String, - parameterTypes: Array -): Boolean { - val arity = parameterTypes.size - val theName = methodNameAdapters[name to arity] ?: name - val spec = findSpecific(context, theName, parameterTypes) ?: return false - val owner = context.javaClass.asm - - invokeAlgebraOperation( - owner = owner.internalName, - method = theName, - descriptor = Type.getMethodDescriptor(primitiveMaskBoxed, *mapTypes(spec, parameterTypes).toTypedArray()), - expectedArity = arity, - opcode = INVOKEVIRTUAL - ) - - return true -} - -/** - * Builds specialized [context] call with option to fallback to generic algebra operation accepting [String]. - * - * @author Iaroslav Postovalov - */ -internal inline fun AsmBuilder.buildAlgebraOperationCall( - context: Algebra, - name: String, - fallbackMethodName: String, - parameterTypes: Array, - parameters: AsmBuilder.() -> Unit -) { - contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) } - val arity = parameterTypes.size - loadAlgebra() - if (!buildExpectationStack(context, name, parameterTypes)) loadStringConstant(name) - parameters() - - if (!tryInvokeSpecific(context, name, parameterTypes)) invokeAlgebraOperation( - owner = AsmBuilder.ALGEBRA_TYPE.internalName, - method = fallbackMethodName, - - descriptor = Type.getMethodDescriptor( - AsmBuilder.OBJECT_TYPE, - AsmBuilder.STRING_TYPE, - *Array(arity) { AsmBuilder.OBJECT_TYPE } - ), - - expectedArity = arity - ) -} diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt index 5eebfe43d..a1687c1c7 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt @@ -10,15 +10,11 @@ import kotlin.test.Test import kotlin.test.assertEquals internal class TestAsmAlgebras { - @Test fun space() { val res1 = ByteRing.mstInSpace { - binaryOperation( - "+", - - unaryOperation( - "+", + binaryOperation("+")( + unaryOperation("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( add(number(1), number(1)), 2 @@ -30,11 +26,8 @@ internal class TestAsmAlgebras { }("x" to 2.toByte()) val res2 = ByteRing.mstInSpace { - binaryOperation( - "+", - - unaryOperation( - "+", + binaryOperation("+")( + unaryOperation("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( add(number(1), number(1)), 2 @@ -51,11 +44,8 @@ internal class TestAsmAlgebras { @Test fun ring() { val res1 = ByteRing.mstInRing { - binaryOperation( - "+", - - unaryOperation( - "+", + binaryOperation("+")( + unaryOperation("+")( (symbol("x") - (2.toByte() + (multiply( add(number(1), number(1)), 2 @@ -67,17 +57,13 @@ internal class TestAsmAlgebras { }("x" to 3.toByte()) val res2 = ByteRing.mstInRing { - binaryOperation( - "+", - - unaryOperation( - "+", + binaryOperation("+")( + unaryOperation("+")( (symbol("x") - (2.toByte() + (multiply( add(number(1), number(1)), 2 ) + 1.toByte()))) * 3.0 - 1.toByte() ), - number(1) ) * number(2) }.compile()("x" to 3.toByte()) @@ -88,8 +74,7 @@ internal class TestAsmAlgebras { @Test fun field() { val res1 = RealField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation( - "+", + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -97,8 +82,7 @@ internal class TestAsmAlgebras { }("x" to 2.0) val res2 = RealField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation( - "+", + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt index 7f4d453f7..acd9e21ea 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt @@ -1,10 +1,11 @@ package kscience.kmath.asm -import kscience.kmath.asm.compile +import kscience.kmath.ast.mstInExtendedField import kscience.kmath.ast.mstInField import kscience.kmath.ast.mstInSpace import kscience.kmath.expressions.invoke import kscience.kmath.operations.RealField +import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -28,4 +29,13 @@ internal class TestAsmExpressions { val res = RealField.mstInField { symbol("x") * 2 }("x" to 2.0) assertEquals(4.0, res) } + + @Test + fun testMultipleCalls() { + val e = RealField.mstInExtendedField { sin(symbol("x")).pow(4) - 6 * symbol("x") / tanh(symbol("x")) }.compile() + val r = Random(0) + var s = 0.0 + repeat(1000000) { s += e("x" to r.nextDouble()) } + println(s) + } } diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt index eb5a1c8f3..ce9e602d3 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt @@ -46,7 +46,7 @@ internal class TestAsmSpecialization { @Test fun testPower() { val expr = RealField - .mstInField { binaryOperation("power")(symbol("x"), number(2)) } + .mstInField { binaryOperation("pow")(symbol("x"), number(2)) } .compile() assertEquals(4.0, expr("x" to 2.0)) diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt index 7b89c74fa..1011515c8 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt @@ -17,6 +17,6 @@ internal class TestAsmVariables { @Test fun testVariableWithoutDefaultFails() { val expr = ByteRing.mstInRing { symbol("x") } - assertFailsWith { expr() } + assertFailsWith { expr() } } } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index 19ca1a4cc..2661525fb 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -20,12 +20,14 @@ public interface Algebra { /** * Dynamically dispatches an unary operation with name [operation]. */ - public fun unaryOperation(operation: String): (arg: T) -> T + public fun unaryOperation(operation: String): (arg: T) -> T = + error("Unary operation $operation not defined in $this") /** * Dynamically dispatches a binary operation with name [operation]. */ - public fun binaryOperation(operation: String): (left: T, right: T) -> T + public fun binaryOperation(operation: String): (left: T, right: T) -> T = + error("Binary operation $operation not defined in $this") } /** @@ -161,13 +163,13 @@ public interface SpaceOperations : Algebra { override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { PLUS_OPERATION -> { arg -> arg } MINUS_OPERATION -> { arg -> -arg } - else -> error("Unary operation $operation not defined in $this") + else -> super.unaryOperation(operation) } override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { PLUS_OPERATION -> ::add MINUS_OPERATION -> { left, right -> left - right } - else -> error("Binary operation $operation not defined in $this") + else -> super.binaryOperation(operation) } public companion object { diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt index 611222d34..cd2bd0417 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt @@ -31,7 +31,7 @@ public interface ExtendedFieldOperations : PowerOperations.SQRT_OPERATION -> ::sqrt ExponentialOperations.EXP_OPERATION -> ::exp ExponentialOperations.LN_OPERATION -> ::ln - else -> super.unaryOperation(operation) + else -> super.unaryOperation(operation) } } From cc45e3683b702b8c8e637af66d7cf07d67dcbd24 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 8 Dec 2020 16:16:32 +0700 Subject: [PATCH 04/39] Refactor ASM builder --- .../kscience/kmath/asm/internal/AsmBuilder.kt | 129 +++++++----------- .../kmath/asm/internal/codegenUtils.kt | 2 - 2 files changed, 53 insertions(+), 78 deletions(-) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index 792034232..46051e158 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -6,6 +6,7 @@ import kscience.kmath.expressions.Expression import kscience.kmath.operations.Algebra import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* +import org.objectweb.asm.Type.* import org.objectweb.asm.commons.InstructionAdapter import java.util.stream.Collectors.toMap import kotlin.contracts.InvocationKind @@ -17,13 +18,13 @@ import kotlin.contracts.contract * * @property T the type of AsmExpression to unwrap. * @property className the unique class name of new loaded class. - * @property invokeLabel0Visitor the function to apply to this object when generating invoke method, label 0. + * @property callbackAtInvokeL0 the function to apply to this object when generating invoke method, label 0. * @author Iaroslav Postovalov */ -internal class AsmBuilder internal constructor( +internal class AsmBuilder( classOfT: Class<*>, private val className: String, - private val invokeLabel0Visitor: AsmBuilder.() -> Unit, + private val callbackAtInvokeL0: AsmBuilder.() -> Unit, ) { /** * Internal classloader of [AsmBuilder] with alias to define class from byte array. @@ -45,7 +46,7 @@ internal class AsmBuilder internal constructor( /** * ASM type for new class. */ - private val classType: Type = Type.getObjectType(className.replace(oldChar = '.', newChar = '/'))!! + private val classType: Type = getObjectType(className.replace(oldChar = '.', newChar = '/')) /** * List of constants to provide to the subclass. @@ -57,11 +58,6 @@ internal class AsmBuilder internal constructor( */ private lateinit var invokeMethodVisitor: InstructionAdapter - /** - * States whether this [AsmBuilder] needs to generate constants field. - */ - private var hasConstants: Boolean = true - /** * Subclasses, loads and instantiates [Expression] for given parameters. * @@ -69,6 +65,8 @@ internal class AsmBuilder internal constructor( */ @Suppress("UNCHECKED_CAST") val instance: Expression by lazy { + val hasConstants: Boolean + val classWriter = ClassWriter(ClassWriter.COMPUTE_FRAMES) { visit( V1_8, @@ -82,14 +80,14 @@ internal class AsmBuilder internal constructor( visitMethod( ACC_PUBLIC or ACC_FINAL, "invoke", - Type.getMethodDescriptor(tType, MAP_TYPE), + getMethodDescriptor(tType, MAP_TYPE), "(L${MAP_TYPE.internalName}<${STRING_TYPE.descriptor}+${tType.descriptor}>;)${tType.descriptor}", null ).instructionAdapter { invokeMethodVisitor = this visitCode() val l0 = label() - invokeLabel0Visitor() + callbackAtInvokeL0() areturn(tType) val l1 = label() @@ -99,7 +97,7 @@ internal class AsmBuilder internal constructor( null, l0, l1, - invokeThisVar + 0 ) visitLocalVariable( @@ -108,7 +106,7 @@ internal class AsmBuilder internal constructor( "L${MAP_TYPE.internalName}<${STRING_TYPE.descriptor}+${tType.descriptor}>;", l0, l1, - invokeArgumentsVar + 1 ) visitMaxs(0, 2) @@ -118,7 +116,7 @@ internal class AsmBuilder internal constructor( visitMethod( ACC_PUBLIC or ACC_FINAL or ACC_BRIDGE or ACC_SYNTHETIC, "invoke", - Type.getMethodDescriptor(OBJECT_TYPE, MAP_TYPE), + getMethodDescriptor(OBJECT_TYPE, MAP_TYPE), null, null ).instructionAdapter { @@ -128,7 +126,7 @@ internal class AsmBuilder internal constructor( val l0 = label() load(thisVar, OBJECT_TYPE) load(argumentsVar, MAP_TYPE) - invokevirtual(classType.internalName, "invoke", Type.getMethodDescriptor(tType, MAP_TYPE), false) + invokevirtual(classType.internalName, "invoke", getMethodDescriptor(tType, MAP_TYPE), false) areturn(tType) val l1 = label() @@ -160,32 +158,30 @@ internal class AsmBuilder internal constructor( visitMethod( ACC_PUBLIC, "", - Type.getMethodDescriptor(Type.VOID_TYPE, *OBJECT_ARRAY_TYPE.wrapToArrayIf { hasConstants }), + getMethodDescriptor(VOID_TYPE, *OBJECT_ARRAY_TYPE.wrapToArrayIf { hasConstants }), null, null ).instructionAdapter { - val thisVar = 0 - val constantsVar = 1 val l0 = label() - load(thisVar, classType) - invokespecial(OBJECT_TYPE.internalName, "", Type.getMethodDescriptor(Type.VOID_TYPE), false) + load(0, classType) + invokespecial(OBJECT_TYPE.internalName, "", getMethodDescriptor(VOID_TYPE), false) label() - load(thisVar, classType) + load(0, classType) if (hasConstants) { label() - load(thisVar, classType) - load(constantsVar, OBJECT_ARRAY_TYPE) + load(0, classType) + load(1, OBJECT_ARRAY_TYPE) putfield(classType.internalName, "constants", OBJECT_ARRAY_TYPE.descriptor) } label() visitInsn(RETURN) val l4 = label() - visitLocalVariable("this", classType.descriptor, null, l0, l4, thisVar) + visitLocalVariable("this", classType.descriptor, null, l0, l4, 0) if (hasConstants) - visitLocalVariable("constants", OBJECT_ARRAY_TYPE.descriptor, null, l0, l4, constantsVar) + visitLocalVariable("constants", OBJECT_ARRAY_TYPE.descriptor, null, l0, l4, 1) visitMaxs(0, 3) visitEnd() @@ -218,7 +214,7 @@ internal class AsmBuilder internal constructor( /** * Loads `this` variable. */ - private fun loadThis(): Unit = invokeMethodVisitor.load(invokeThisVar, classType) + private fun loadThis(): Unit = invokeMethodVisitor.load(0, classType) /** * Either loads a numeric constant [value] from the class's constants field or boxes a primitive @@ -230,12 +226,12 @@ internal class AsmBuilder internal constructor( if (primitive != null) { when (primitive) { - Type.BYTE_TYPE -> invokeMethodVisitor.iconst(value.toInt()) - Type.DOUBLE_TYPE -> invokeMethodVisitor.dconst(value.toDouble()) - Type.FLOAT_TYPE -> invokeMethodVisitor.fconst(value.toFloat()) - Type.LONG_TYPE -> invokeMethodVisitor.lconst(value.toLong()) - Type.INT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) - Type.SHORT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) + BYTE_TYPE -> invokeMethodVisitor.iconst(value.toInt()) + DOUBLE_TYPE -> invokeMethodVisitor.dconst(value.toDouble()) + FLOAT_TYPE -> invokeMethodVisitor.fconst(value.toFloat()) + LONG_TYPE -> invokeMethodVisitor.lconst(value.toLong()) + INT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) + SHORT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) } box(primitive) @@ -254,7 +250,7 @@ internal class AsmBuilder internal constructor( invokeMethodVisitor.invokestatic( r.internalName, "valueOf", - Type.getMethodDescriptor(r, primitive), + getMethodDescriptor(r, primitive), false ) } @@ -263,13 +259,13 @@ internal class AsmBuilder internal constructor( * Loads a variable [name] from arguments [Map] parameter of [Expression.invoke]. */ fun loadVariable(name: String): Unit = invokeMethodVisitor.run { - load(invokeArgumentsVar, MAP_TYPE) + load(1, MAP_TYPE) aconst(name) invokestatic( MAP_INTRINSICS_TYPE.internalName, "getOrFail", - Type.getMethodDescriptor(OBJECT_TYPE, MAP_TYPE, STRING_TYPE), + getMethodDescriptor(OBJECT_TYPE, MAP_TYPE, STRING_TYPE), false ) @@ -283,100 +279,81 @@ internal class AsmBuilder internal constructor( val arity = `interface`.methods.find { it.name == "invoke" }?.parameterCount ?: error("Provided function object doesn't contain invoke method") - val type = Type.getType(`interface`) + val type = getType(`interface`) loadObjectConstant(function, type) parameters(this) invokeMethodVisitor.invokeinterface( type.internalName, "invoke", - Type.getMethodDescriptor(OBJECT_TYPE, *Array(arity) { OBJECT_TYPE}), + getMethodDescriptor(OBJECT_TYPE, *Array(arity) { OBJECT_TYPE }), ) invokeMethodVisitor.checkcast(tType) } - internal companion object { - /** - * Index of `this` variable in invoke method of the built subclass. - */ - private const val invokeThisVar: Int = 0 - - /** - * Index of `arguments` variable in invoke method of the built subclass. - */ - private const val invokeArgumentsVar: Int = 1 - - /** - * Maps JVM primitive numbers boxed types to their primitive ASM types. - */ - private val SIGNATURE_LETTERS: Map, Type> by lazy { - hashMapOf( - java.lang.Byte::class.java to Type.BYTE_TYPE, - java.lang.Short::class.java to Type.SHORT_TYPE, - java.lang.Integer::class.java to Type.INT_TYPE, - java.lang.Long::class.java to Type.LONG_TYPE, - java.lang.Float::class.java to Type.FLOAT_TYPE, - java.lang.Double::class.java to Type.DOUBLE_TYPE - ) - } - + companion object { /** * Maps JVM primitive numbers boxed ASM types to their primitive ASM types. */ - private val BOXED_TO_PRIMITIVES: Map by lazy { SIGNATURE_LETTERS.mapKeys { (k, _) -> k.asm } } + private val BOXED_TO_PRIMITIVES: Map by lazy { + hashMapOf( + Byte::class.java.asm to BYTE_TYPE, + Short::class.java.asm to SHORT_TYPE, + Integer::class.java.asm to INT_TYPE, + Long::class.java.asm to LONG_TYPE, + Float::class.java.asm to FLOAT_TYPE, + Double::class.java.asm to DOUBLE_TYPE, + ) + } /** * Maps JVM primitive numbers boxed ASM types to their primitive ASM types. */ private val PRIMITIVES_TO_BOXED: Map by lazy { BOXED_TO_PRIMITIVES.entries.stream().collect( - toMap( - Map.Entry::value, - Map.Entry::key - ) + toMap(Map.Entry::value, Map.Entry::key), ) } /** * ASM type for [Expression]. */ - internal val EXPRESSION_TYPE: Type by lazy { Type.getObjectType("kscience/kmath/expressions/Expression") } + val EXPRESSION_TYPE: Type by lazy { getObjectType("kscience/kmath/expressions/Expression") } /** * ASM type for [java.lang.Number]. */ - internal val NUMBER_TYPE: Type by lazy { Type.getObjectType("java/lang/Number") } + val NUMBER_TYPE: Type by lazy { getObjectType("java/lang/Number") } /** * ASM type for [java.util.Map]. */ - internal val MAP_TYPE: Type by lazy { Type.getObjectType("java/util/Map") } + val MAP_TYPE: Type by lazy { getObjectType("java/util/Map") } /** * ASM type for [java.lang.Object]. */ - internal val OBJECT_TYPE: Type by lazy { Type.getObjectType("java/lang/Object") } + val OBJECT_TYPE: Type by lazy { getObjectType("java/lang/Object") } /** * ASM type for array of [java.lang.Object]. */ - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "RemoveRedundantQualifierName") - internal val OBJECT_ARRAY_TYPE: Type by lazy { Type.getType("[Ljava/lang/Object;") } + val OBJECT_ARRAY_TYPE: Type by lazy { getType("[Ljava/lang/Object;") } /** * ASM type for [Algebra]. */ - internal val ALGEBRA_TYPE: Type by lazy { Type.getObjectType("kscience/kmath/operations/Algebra") } + val ALGEBRA_TYPE: Type by lazy { getObjectType("kscience/kmath/operations/Algebra") } /** * ASM type for [java.lang.String]. */ - internal val STRING_TYPE: Type by lazy { Type.getObjectType("java/lang/String") } + val STRING_TYPE: Type by lazy { getObjectType("java/lang/String") } /** * ASM type for MapIntrinsics. */ - internal val MAP_INTRINSICS_TYPE: Type by lazy { Type.getObjectType("kscience/kmath/asm/internal/MapIntrinsics") } + val MAP_INTRINSICS_TYPE: Type by lazy { getObjectType("kscience/kmath/asm/internal/MapIntrinsics") } } } diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt index d301ddf15..6d5d19d42 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt @@ -91,5 +91,3 @@ internal inline fun ClassWriter.visitField( contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return visitField(access, name, descriptor, signature, value).apply(block) } - - From 95c1504c00006eb4f5096b569cede64788032f93 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Wed, 9 Dec 2020 11:41:37 +0700 Subject: [PATCH 05/39] Add cast microoptimization to AsmBuilder --- .../kscience/kmath/asm/internal/AsmBuilder.kt | 35 ++++++------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index 46051e158..eb0f60f4d 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -3,7 +3,6 @@ package kscience.kmath.asm.internal import kscience.kmath.asm.internal.AsmBuilder.ClassLoader import kscience.kmath.ast.MST import kscience.kmath.expressions.Expression -import kscience.kmath.operations.Algebra import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* import org.objectweb.asm.Type.* @@ -74,7 +73,7 @@ internal class AsmBuilder( classType.internalName, "${OBJECT_TYPE.descriptor}L${EXPRESSION_TYPE.internalName}<${tType.descriptor}>;", OBJECT_TYPE.internalName, - arrayOf(EXPRESSION_TYPE.internalName) + arrayOf(EXPRESSION_TYPE.internalName), ) visitMethod( @@ -82,7 +81,7 @@ internal class AsmBuilder( "invoke", getMethodDescriptor(tType, MAP_TYPE), "(L${MAP_TYPE.internalName}<${STRING_TYPE.descriptor}+${tType.descriptor}>;)${tType.descriptor}", - null + null, ).instructionAdapter { invokeMethodVisitor = this visitCode() @@ -97,7 +96,7 @@ internal class AsmBuilder( null, l0, l1, - 0 + 0, ) visitLocalVariable( @@ -106,7 +105,7 @@ internal class AsmBuilder( "L${MAP_TYPE.internalName}<${STRING_TYPE.descriptor}+${tType.descriptor}>;", l0, l1, - 1 + 1, ) visitMaxs(0, 2) @@ -118,14 +117,12 @@ internal class AsmBuilder( "invoke", getMethodDescriptor(OBJECT_TYPE, MAP_TYPE), null, - null + null, ).instructionAdapter { - val thisVar = 0 - val argumentsVar = 1 visitCode() val l0 = label() - load(thisVar, OBJECT_TYPE) - load(argumentsVar, MAP_TYPE) + load(0, OBJECT_TYPE) + load(1, MAP_TYPE) invokevirtual(classType.internalName, "invoke", getMethodDescriptor(tType, MAP_TYPE), false) areturn(tType) val l1 = label() @@ -136,7 +133,7 @@ internal class AsmBuilder( null, l0, l1, - thisVar + 0, ) visitMaxs(0, 2) @@ -152,7 +149,7 @@ internal class AsmBuilder( descriptor = OBJECT_ARRAY_TYPE.descriptor, signature = null, value = null, - block = FieldVisitor::visitEnd + block = FieldVisitor::visitEnd, ) visitMethod( @@ -208,7 +205,7 @@ internal class AsmBuilder( getfield(classType.internalName, "constants", OBJECT_ARRAY_TYPE.descriptor) iconst(idx) visitInsn(AALOAD) - checkcast(type) + if (type != OBJECT_TYPE) checkcast(type) } /** @@ -266,7 +263,7 @@ internal class AsmBuilder( MAP_INTRINSICS_TYPE.internalName, "getOrFail", getMethodDescriptor(OBJECT_TYPE, MAP_TYPE, STRING_TYPE), - false + false, ) checkcast(tType) @@ -321,11 +318,6 @@ internal class AsmBuilder( */ val EXPRESSION_TYPE: Type by lazy { getObjectType("kscience/kmath/expressions/Expression") } - /** - * ASM type for [java.lang.Number]. - */ - val NUMBER_TYPE: Type by lazy { getObjectType("java/lang/Number") } - /** * ASM type for [java.util.Map]. */ @@ -341,11 +333,6 @@ internal class AsmBuilder( */ val OBJECT_ARRAY_TYPE: Type by lazy { getType("[Ljava/lang/Object;") } - /** - * ASM type for [Algebra]. - */ - val ALGEBRA_TYPE: Type by lazy { getObjectType("kscience/kmath/operations/Algebra") } - /** * ASM type for [java.lang.String]. */ From 07d6d891928d89d3eb14917cfbf78d790e4883b8 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Wed, 9 Dec 2020 14:43:37 +0700 Subject: [PATCH 06/39] Replace reflective constructor invocation with method handle --- .../kscience/kmath/asm/internal/AsmBuilder.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index eb0f60f4d..d146afeee 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -7,6 +7,8 @@ import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* import org.objectweb.asm.Type.* import org.objectweb.asm.commons.InstructionAdapter +import java.lang.invoke.MethodHandles +import java.lang.invoke.MethodType import java.util.stream.Collectors.toMap import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -187,13 +189,14 @@ internal class AsmBuilder( visitEnd() } -// java.io.File("dump.class").writeBytes(classWriter.toByteArray()) + val cls = classLoader.defineClass(className, classWriter.toByteArray()) + val l = MethodHandles.publicLookup() - classLoader - .defineClass(className, classWriter.toByteArray()) - .constructors - .first() - .newInstance(*(constants.toTypedArray().wrapToArrayIf { hasConstants })) as Expression + if (hasConstants) + l.findConstructor(cls, MethodType.methodType(Void.TYPE, Array::class.java)) + .invoke(constants.toTypedArray()) as Expression + else + l.findConstructor(cls, MethodType.methodType(Void.TYPE)).invoke() as Expression } /** @@ -248,7 +251,7 @@ internal class AsmBuilder( r.internalName, "valueOf", getMethodDescriptor(r, primitive), - false + false, ) } From bdd33ca6ca608663882616f1b8147fe0f65d070c Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 00:40:18 +0700 Subject: [PATCH 07/39] Add dependencies needed for ESTree codegen --- kmath-ast/build.gradle.kts | 6 + kmath-ast/src/jsMain/kotlin/Codegen.kt | 0 kmath-ast/src/jsMain/kotlin/astring.d.ts | 50 ++ kmath-ast/src/jsMain/kotlin/astring.global.kt | 17 + kmath-ast/src/jsMain/kotlin/astring.kt | 32 + kmath-ast/src/jsMain/kotlin/emitter.d.ts | 19 + kmath-ast/src/jsMain/kotlin/emitter.kt | 18 + kmath-ast/src/jsMain/kotlin/estree.d.ts | 569 +++++++++++++++ kmath-ast/src/jsMain/kotlin/estree.kt | 647 ++++++++++++++++++ .../src/jsMain/kotlin/lib.es2015.iterable.kt | 40 ++ kmath-ast/src/jsMain/kotlin/lib.es5.kt | 86 +++ kmath-ast/src/jsMain/kotlin/stream.d.ts | 5 + kmath-ast/src/jsMain/kotlin/stream.kt | 9 + 13 files changed, 1498 insertions(+) create mode 100644 kmath-ast/src/jsMain/kotlin/Codegen.kt create mode 100644 kmath-ast/src/jsMain/kotlin/astring.d.ts create mode 100644 kmath-ast/src/jsMain/kotlin/astring.global.kt create mode 100644 kmath-ast/src/jsMain/kotlin/astring.kt create mode 100644 kmath-ast/src/jsMain/kotlin/emitter.d.ts create mode 100644 kmath-ast/src/jsMain/kotlin/emitter.kt create mode 100644 kmath-ast/src/jsMain/kotlin/estree.d.ts create mode 100644 kmath-ast/src/jsMain/kotlin/estree.kt create mode 100644 kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt create mode 100644 kmath-ast/src/jsMain/kotlin/lib.es5.kt create mode 100644 kmath-ast/src/jsMain/kotlin/stream.d.ts create mode 100644 kmath-ast/src/jsMain/kotlin/stream.kt diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index 3e3c0475f..e3884025d 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -9,6 +9,12 @@ kotlin.sourceSets { } } + jsMain { + dependencies { + implementation(npm("astring", "1.4.3")) + } + } + jvmMain { dependencies { api("com.github.h0tk3y.betterParse:better-parse:0.4.0") diff --git a/kmath-ast/src/jsMain/kotlin/Codegen.kt b/kmath-ast/src/jsMain/kotlin/Codegen.kt new file mode 100644 index 000000000..e69de29bb diff --git a/kmath-ast/src/jsMain/kotlin/astring.d.ts b/kmath-ast/src/jsMain/kotlin/astring.d.ts new file mode 100644 index 000000000..22cd7e980 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/astring.d.ts @@ -0,0 +1,50 @@ +// Type definitions for astring 1.3 +// Project: https://github.com/davidbonnet/astring +// Definitions by: Nikolaj Kappler +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +import * as ESTree from 'estree'; +import 'node'; +import { Stream } from 'stream'; + +export interface Options { + /** string to use for indentation (defaults to " ") */ + indent?: string; + /** string to use for line endings (defaults to "\n") */ + lineEnd?: string; + /** indent level to start from (defaults to 0) */ + startingIndentLevel?: number; + /** generate comments if true (defaults to false) */ + comments?: boolean; + /** custom code generator (defaults to astring.baseGenerator) */ + generator?: object; + /** source map generator (defaults to null), see https://github.com/mozilla/source-map#sourcemapgenerator */ + sourceMap?: any; +} + +/** Returns a string representing the rendered code of the provided AST `node`. However, if an `output` stream is provided in the options, it writes to that stream and returns it. */ +export function generate(node: ESTree.Node, options?: Options): string; +/** Returns a string representing the rendered code of the provided AST `node`. However, if an `output` stream is provided in the options, it writes to that stream and returns it. */ +export function generate(node: ESTree.Node, options: Options & { + /** output stream to write the rendered code to (defaults to null) */ + output: Stream; +}): Stream; + +/** + * A code generator consists of a mapping of node names and functions that take two arguments: `node` and `state`. + * The `node` points to the node from which to generate the code and the `state` exposes the `write` method that takes generated code strings. + */ +export type Generator = { [key in ESTree.Node["type"]]: (node: Extract, state: { write(s: string): void }) => void }; + +/** Base generator that can be used to extend Astring. See https://github.com/davidbonnet/astring#extending */ +export const baseGenerator: Generator; + +declare global { + interface astring { + generate: typeof generate; + /** Base generator that can be used to extend Astring. See https://github.com/davidbonnet/astring#extending */ + baseGenerator: Generator; + } + const astring: astring; +} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/astring.global.kt b/kmath-ast/src/jsMain/kotlin/astring.global.kt new file mode 100644 index 000000000..78c771f26 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/astring.global.kt @@ -0,0 +1,17 @@ +@file:JsQualifier("global") +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "PackageDirectoryMismatch", "ClassName" +) + +package global + +import Generator + +@Suppress("EXTERNAL_DELEGATION", "NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface astring { + var generate: Any + var baseGenerator: Generator + + companion object : astring by definedExternally +} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/astring.kt b/kmath-ast/src/jsMain/kotlin/astring.kt new file mode 100644 index 000000000..e9ab6f627 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/astring.kt @@ -0,0 +1,32 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation" +) + +external interface Options { + var indent: String? + get() = definedExternally + set(value) = definedExternally + var lineEnd: String? + get() = definedExternally + set(value) = definedExternally + var startingIndentLevel: Number? + get() = definedExternally + set(value) = definedExternally + var comments: Boolean? + get() = definedExternally + set(value) = definedExternally + var generator: Any? + get() = definedExternally + set(value) = definedExternally + var sourceMap: Any? + get() = definedExternally + set(value) = definedExternally +} + +external fun generate(node: BaseNode, options: Options /* Options & `T$0` */ = definedExternally): String + +external fun generate(node: BaseNode): String + +typealias Generator = Any + +external var baseGenerator: Generator \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/emitter.d.ts b/kmath-ast/src/jsMain/kotlin/emitter.d.ts new file mode 100644 index 000000000..ea0319cd6 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/emitter.d.ts @@ -0,0 +1,19 @@ +export class Emitter { + constructor(obj: any) + constructor() + + on(event: string, fn: () => void) + + off(event: string, fn: () => void) + + once(event: string, fn: () => void) + + emit(event: string, ...any: any[]) + + listeners(event: string): (() => void)[] + + hasListeners(event: string): boolean +} + + +function mixin(obj: any): any diff --git a/kmath-ast/src/jsMain/kotlin/emitter.kt b/kmath-ast/src/jsMain/kotlin/emitter.kt new file mode 100644 index 000000000..ad0a16bf7 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/emitter.kt @@ -0,0 +1,18 @@ +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", + "OVERRIDING_FINAL_MEMBER", + "RETURN_TYPE_MISMATCH_ON_OVERRIDE", + "CONFLICTING_OVERLOADS", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "SortModifiers" +) + +external open class Emitter { + constructor(obj: Any) + constructor() + + open fun on(event: String, fn: () -> Unit) + open fun off(event: String, fn: () -> Unit) + open fun once(event: String, fn: () -> Unit) + open fun emit(event: String, vararg any: Any) + open fun listeners(event: String): Array<() -> Unit> + open fun hasListeners(event: String): Boolean +} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/estree.d.ts b/kmath-ast/src/jsMain/kotlin/estree.d.ts new file mode 100644 index 000000000..927477c66 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/estree.d.ts @@ -0,0 +1,569 @@ +// Type definitions for ESTree AST specification +// Project: https://github.com/estree/estree +// Definitions by: RReverser +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +// This definition file follows a somewhat unusual format. ESTree allows +// runtime type checks based on the `type` parameter. In order to explain this +// to typescript we want to use discriminated union types: +// https://github.com/Microsoft/TypeScript/pull/9163 +// +// For ESTree this is a bit tricky because the high level interfaces like +// Node or Function are pulling double duty. We want to pass common fields down +// to the interfaces that extend them (like Identifier or +// ArrowFunctionExpression), but you can't extend a type union or enforce +// common fields on them. So we've split the high level interfaces into two +// types, a base type which passes down inhereted fields, and a type union of +// all types which extend the base type. Only the type union is exported, and +// the union is how other types refer to the collection of inheriting types. +// +// This makes the definitions file here somewhat more difficult to maintain, +// but it has the notable advantage of making ESTree much easier to use as +// an end user. + +interface BaseNodeWithoutComments { + // Every leaf interface that extends BaseNode must specify a type property. + // The type property should be a string literal. For example, Identifier + // has: `type: "Identifier"` + type: string; + loc?: SourceLocation | null; + range?: [number, number]; +} + +interface BaseNode extends BaseNodeWithoutComments { + leadingComments?: Array; + trailingComments?: Array; +} + +export type Node = + Identifier | Literal | Program | Function | SwitchCase | CatchClause | + VariableDeclarator | Statement | Expression | Property | + AssignmentProperty | Super | TemplateElement | SpreadElement | Pattern | + ClassBody | Class | MethodDefinition | ModuleDeclaration | ModuleSpecifier; + +export interface Comment extends BaseNodeWithoutComments { + type: "Line" | "Block"; + value: string; +} + +interface SourceLocation { + source?: string | null; + start: Position; + end: Position; +} + +export interface Position { + /** >= 1 */ + line: number; + /** >= 0 */ + column: number; +} + +export interface Program extends BaseNode { + type: "Program"; + sourceType: "script" | "module"; + body: Array; + comments?: Array; +} + +export interface Directive extends BaseNode { + type: "ExpressionStatement"; + expression: Literal; + directive: string; +} + +interface BaseFunction extends BaseNode { + params: Array; + generator?: boolean; + async?: boolean; + // The body is either BlockStatement or Expression because arrow functions + // can have a body that's either. FunctionDeclarations and + // FunctionExpressions have only BlockStatement bodies. + body: BlockStatement | Expression; +} + +export type Function = + FunctionDeclaration | FunctionExpression | ArrowFunctionExpression; + +export type Statement = + ExpressionStatement | BlockStatement | EmptyStatement | + DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | + BreakStatement | ContinueStatement | IfStatement | SwitchStatement | + ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | + ForStatement | ForInStatement | ForOfStatement | Declaration; + +interface BaseStatement extends BaseNode { } + +export interface EmptyStatement extends BaseStatement { + type: "EmptyStatement"; +} + +export interface BlockStatement extends BaseStatement { + type: "BlockStatement"; + body: Array; + innerComments?: Array; +} + +export interface ExpressionStatement extends BaseStatement { + type: "ExpressionStatement"; + expression: Expression; +} + +export interface IfStatement extends BaseStatement { + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate?: Statement | null; +} + +export interface LabeledStatement extends BaseStatement { + type: "LabeledStatement"; + label: Identifier; + body: Statement; +} + +export interface BreakStatement extends BaseStatement { + type: "BreakStatement"; + label?: Identifier | null; +} + +export interface ContinueStatement extends BaseStatement { + type: "ContinueStatement"; + label?: Identifier | null; +} + +export interface WithStatement extends BaseStatement { + type: "WithStatement"; + object: Expression; + body: Statement; +} + +export interface SwitchStatement extends BaseStatement { + type: "SwitchStatement"; + discriminant: Expression; + cases: Array; +} + +export interface ReturnStatement extends BaseStatement { + type: "ReturnStatement"; + argument?: Expression | null; +} + +export interface ThrowStatement extends BaseStatement { + type: "ThrowStatement"; + argument: Expression; +} + +export interface TryStatement extends BaseStatement { + type: "TryStatement"; + block: BlockStatement; + handler?: CatchClause | null; + finalizer?: BlockStatement | null; +} + +export interface WhileStatement extends BaseStatement { + type: "WhileStatement"; + test: Expression; + body: Statement; +} + +export interface DoWhileStatement extends BaseStatement { + type: "DoWhileStatement"; + body: Statement; + test: Expression; +} + +export interface ForStatement extends BaseStatement { + type: "ForStatement"; + init?: VariableDeclaration | Expression | null; + test?: Expression | null; + update?: Expression | null; + body: Statement; +} + +interface BaseForXStatement extends BaseStatement { + left: VariableDeclaration | Pattern; + right: Expression; + body: Statement; +} + +export interface ForInStatement extends BaseForXStatement { + type: "ForInStatement"; +} + +export interface DebuggerStatement extends BaseStatement { + type: "DebuggerStatement"; +} + +export type Declaration = + FunctionDeclaration | VariableDeclaration | ClassDeclaration; + +interface BaseDeclaration extends BaseStatement { } + +export interface FunctionDeclaration extends BaseFunction, BaseDeclaration { + type: "FunctionDeclaration"; + /** It is null when a function declaration is a part of the `export default function` statement */ + id: Identifier | null; + body: BlockStatement; +} + +export interface VariableDeclaration extends BaseDeclaration { + type: "VariableDeclaration"; + declarations: Array; + kind: "var" | "let" | "const"; +} + +export interface VariableDeclarator extends BaseNode { + type: "VariableDeclarator"; + id: Pattern; + init?: Expression | null; +} + +type Expression = + ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | + ArrowFunctionExpression | YieldExpression | Literal | UnaryExpression | + UpdateExpression | BinaryExpression | AssignmentExpression | + LogicalExpression | MemberExpression | ConditionalExpression | + CallExpression | NewExpression | SequenceExpression | TemplateLiteral | + TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | + AwaitExpression | ImportExpression | ChainExpression; + +export interface BaseExpression extends BaseNode { } + +type ChainElement = SimpleCallExpression | MemberExpression; + +export interface ChainExpression extends BaseExpression { + type: "ChainExpression"; + expression: ChainElement; +} + +export interface ThisExpression extends BaseExpression { + type: "ThisExpression"; +} + +export interface ArrayExpression extends BaseExpression { + type: "ArrayExpression"; + elements: Array; +} + +export interface ObjectExpression extends BaseExpression { + type: "ObjectExpression"; + properties: Array; +} + +export interface Property extends BaseNode { + type: "Property"; + key: Expression; + value: Expression | Pattern; // Could be an AssignmentProperty + kind: "init" | "get" | "set"; + method: boolean; + shorthand: boolean; + computed: boolean; +} + +export interface FunctionExpression extends BaseFunction, BaseExpression { + id?: Identifier | null; + type: "FunctionExpression"; + body: BlockStatement; +} + +export interface SequenceExpression extends BaseExpression { + type: "SequenceExpression"; + expressions: Array; +} + +export interface UnaryExpression extends BaseExpression { + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: true; + argument: Expression; +} + +export interface BinaryExpression extends BaseExpression { + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression; + right: Expression; +} + +export interface AssignmentExpression extends BaseExpression { + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | MemberExpression; + right: Expression; +} + +export interface UpdateExpression extends BaseExpression { + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; +} + +export interface LogicalExpression extends BaseExpression { + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; +} + +export interface ConditionalExpression extends BaseExpression { + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; +} + +interface BaseCallExpression extends BaseExpression { + callee: Expression | Super; + arguments: Array; +} +export type CallExpression = SimpleCallExpression | NewExpression; + +export interface SimpleCallExpression extends BaseCallExpression { + type: "CallExpression"; + optional: boolean; +} + +export interface NewExpression extends BaseCallExpression { + type: "NewExpression"; +} + +export interface MemberExpression extends BaseExpression, BasePattern { + type: "MemberExpression"; + object: Expression | Super; + property: Expression; + computed: boolean; + optional: boolean; +} + +export type Pattern = + Identifier | ObjectPattern | ArrayPattern | RestElement | + AssignmentPattern | MemberExpression; + +interface BasePattern extends BaseNode { } + +export interface SwitchCase extends BaseNode { + type: "SwitchCase"; + test?: Expression | null; + consequent: Array; +} + +export interface CatchClause extends BaseNode { + type: "CatchClause"; + param: Pattern | null; + body: BlockStatement; +} + +export interface Identifier extends BaseNode, BaseExpression, BasePattern { + type: "Identifier"; + name: string; +} + +export type Literal = SimpleLiteral | RegExpLiteral; + +export interface SimpleLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value: string | boolean | number | null; + raw?: string; +} + +export interface RegExpLiteral extends BaseNode, BaseExpression { + type: "Literal"; + value?: RegExp | null; + regex: { + pattern: string; + flags: string; + }; + raw?: string; +} + +export type UnaryOperator = + "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; + +export type BinaryOperator = + "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | + ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "in" | + "instanceof"; + +export type LogicalOperator = "||" | "&&" | "??"; + +export type AssignmentOperator = + "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "<<=" | ">>=" | ">>>=" | + "|=" | "^=" | "&="; + +export type UpdateOperator = "++" | "--"; + +export interface ForOfStatement extends BaseForXStatement { + type: "ForOfStatement"; + await: boolean; +} + +export interface Super extends BaseNode { + type: "Super"; +} + +export interface SpreadElement extends BaseNode { + type: "SpreadElement"; + argument: Expression; +} + +export interface ArrowFunctionExpression extends BaseExpression, BaseFunction { + type: "ArrowFunctionExpression"; + expression: boolean; + body: BlockStatement | Expression; +} + +export interface YieldExpression extends BaseExpression { + type: "YieldExpression"; + argument?: Expression | null; + delegate: boolean; +} + +export interface TemplateLiteral extends BaseExpression { + type: "TemplateLiteral"; + quasis: Array; + expressions: Array; +} + +export interface TaggedTemplateExpression extends BaseExpression { + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; +} + +export interface TemplateElement extends BaseNode { + type: "TemplateElement"; + tail: boolean; + value: { + cooked: string; + raw: string; + }; +} + +export interface AssignmentProperty extends Property { + value: Pattern; + kind: "init"; + method: boolean; // false +} + +export interface ObjectPattern extends BasePattern { + type: "ObjectPattern"; + properties: Array; +} + +export interface ArrayPattern extends BasePattern { + type: "ArrayPattern"; + elements: Array; +} + +export interface RestElement extends BasePattern { + type: "RestElement"; + argument: Pattern; +} + +export interface AssignmentPattern extends BasePattern { + type: "AssignmentPattern"; + left: Pattern; + right: Expression; +} + +export type Class = ClassDeclaration | ClassExpression; +interface BaseClass extends BaseNode { + superClass?: Expression | null; + body: ClassBody; +} + +export interface ClassBody extends BaseNode { + type: "ClassBody"; + body: Array; +} + +export interface MethodDefinition extends BaseNode { + type: "MethodDefinition"; + key: Expression; + value: FunctionExpression; + kind: "constructor" | "method" | "get" | "set"; + computed: boolean; + static: boolean; +} + +export interface ClassDeclaration extends BaseClass, BaseDeclaration { + type: "ClassDeclaration"; + /** It is null when a class declaration is a part of the `export default class` statement */ + id: Identifier | null; +} + +export interface ClassExpression extends BaseClass, BaseExpression { + type: "ClassExpression"; + id?: Identifier | null; +} + +export interface MetaProperty extends BaseExpression { + type: "MetaProperty"; + meta: Identifier; + property: Identifier; +} + +export type ModuleDeclaration = + ImportDeclaration | ExportNamedDeclaration | ExportDefaultDeclaration | + ExportAllDeclaration; +interface BaseModuleDeclaration extends BaseNode { } + +export type ModuleSpecifier = + ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | + ExportSpecifier; +interface BaseModuleSpecifier extends BaseNode { + local: Identifier; +} + +export interface ImportDeclaration extends BaseModuleDeclaration { + type: "ImportDeclaration"; + specifiers: Array; + source: Literal; +} + +export interface ImportSpecifier extends BaseModuleSpecifier { + type: "ImportSpecifier"; + imported: Identifier; +} + +export interface ImportExpression extends BaseExpression { + type: "ImportExpression"; + source: Expression; +} + +export interface ImportDefaultSpecifier extends BaseModuleSpecifier { + type: "ImportDefaultSpecifier"; +} + +export interface ImportNamespaceSpecifier extends BaseModuleSpecifier { + type: "ImportNamespaceSpecifier"; +} + +export interface ExportNamedDeclaration extends BaseModuleDeclaration { + type: "ExportNamedDeclaration"; + declaration?: Declaration | null; + specifiers: Array; + source?: Literal | null; +} + +export interface ExportSpecifier extends BaseModuleSpecifier { + type: "ExportSpecifier"; + exported: Identifier; +} + +export interface ExportDefaultDeclaration extends BaseModuleDeclaration { + type: "ExportDefaultDeclaration"; + declaration: Declaration | Expression; +} + +export interface ExportAllDeclaration extends BaseModuleDeclaration { + type: "ExportAllDeclaration"; + source: Literal; +} + +export interface AwaitExpression extends BaseExpression { + type: "AwaitExpression"; + argument: Expression; +} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/estree.kt b/kmath-ast/src/jsMain/kotlin/estree.kt new file mode 100644 index 000000000..841688f6d --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/estree.kt @@ -0,0 +1,647 @@ +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "ClassName", +) + +import kotlin.js.RegExp + +external interface BaseNodeWithoutComments { + var type: String + var loc: SourceLocation? + get() = definedExternally + set(value) = definedExternally + var range: dynamic /* JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseNode : BaseNodeWithoutComments { + var leadingComments: Array? + get() = definedExternally + set(value) = definedExternally + var trailingComments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Comment : BaseNodeWithoutComments { + override var type: String /* "Line" | "Block" */ + var value: String +} + +external interface SourceLocation { + var source: String? + get() = definedExternally + set(value) = definedExternally + var start: Position + var end: Position +} + +external interface Position { + var line: Number + var column: Number +} + +external interface Program : BaseNode { + override var type: String /* "Program" */ + var sourceType: String /* "script" | "module" */ + var body: Array + var comments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Directive : BaseNode { + override var type: String /* "ExpressionStatement" */ + var expression: dynamic /* SimpleLiteral | RegExpLiteral */ + get() = definedExternally + set(value) = definedExternally + var directive: String +} + +external interface BaseFunction : BaseNode { + var params: Array + var generator: Boolean? + get() = definedExternally + set(value) = definedExternally + var async: Boolean? + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* BlockStatement | ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseStatement : BaseNode + +external interface EmptyStatement : BaseStatement { + override var type: String /* "EmptyStatement" */ +} + +external interface BlockStatement : BaseStatement { + override var type: String /* "BlockStatement" */ + var body: Array + var innerComments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ExpressionStatement : BaseStatement { + override var type: String /* "ExpressionStatement" */ + var expression: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface IfStatement : BaseStatement { + override var type: String /* "IfStatement" */ + var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var consequent: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally + var alternate: dynamic /* ExpressionStatement? | BlockStatement? | EmptyStatement? | DebuggerStatement? | WithStatement? | ReturnStatement? | LabeledStatement? | BreakStatement? | ContinueStatement? | IfStatement? | SwitchStatement? | ThrowStatement? | TryStatement? | WhileStatement? | DoWhileStatement? | ForStatement? | ForInStatement? | ForOfStatement? | FunctionDeclaration? | VariableDeclaration? | ClassDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LabeledStatement : BaseStatement { + override var type: String /* "LabeledStatement" */ + var label: Identifier + var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BreakStatement : BaseStatement { + override var type: String /* "BreakStatement" */ + var label: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface ContinueStatement : BaseStatement { + override var type: String /* "ContinueStatement" */ + var label: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface WithStatement : BaseStatement { + override var type: String /* "WithStatement" */ + var `object`: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SwitchStatement : BaseStatement { + override var type: String /* "SwitchStatement" */ + var discriminant: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var cases: Array +} + +external interface ReturnStatement : BaseStatement { + override var type: String /* "ReturnStatement" */ + var argument: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ThrowStatement : BaseStatement { + override var type: String /* "ThrowStatement" */ + var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TryStatement : BaseStatement { + override var type: String /* "TryStatement" */ + var block: BlockStatement + var handler: CatchClause? + get() = definedExternally + set(value) = definedExternally + var finalizer: BlockStatement? + get() = definedExternally + set(value) = definedExternally +} + +external interface WhileStatement : BaseStatement { + override var type: String /* "WhileStatement" */ + var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DoWhileStatement : BaseStatement { + override var type: String /* "DoWhileStatement" */ + var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally + var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ForStatement : BaseStatement { + override var type: String /* "ForStatement" */ + var init: dynamic /* VariableDeclaration? | ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally + var test: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally + var update: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseForXStatement : BaseStatement { + var left: dynamic /* VariableDeclaration | Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ + get() = definedExternally + set(value) = definedExternally + var right: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ForInStatement : BaseForXStatement { + override var type: String /* "ForInStatement" */ +} + +external interface DebuggerStatement : BaseStatement { + override var type: String /* "DebuggerStatement" */ +} + +external interface BaseDeclaration : BaseStatement + +external interface FunctionDeclaration : BaseFunction, BaseDeclaration { + override var type: String /* "FunctionDeclaration" */ + var id: Identifier? + override var body: BlockStatement +} + +external interface VariableDeclaration : BaseDeclaration { + override var type: String /* "VariableDeclaration" */ + var declarations: Array + var kind: String /* "var" | "let" | "const" */ +} + +external interface VariableDeclarator : BaseNode { + override var type: String /* "VariableDeclarator" */ + var id: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ + get() = definedExternally + set(value) = definedExternally + var init: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseExpression : BaseNode + +external interface ChainExpression : BaseExpression { + override var type: String /* "ChainExpression" */ + var expression: dynamic /* SimpleCallExpression | MemberExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ThisExpression : BaseExpression { + override var type: String /* "ThisExpression" */ +} + +external interface ArrayExpression : BaseExpression { + override var type: String /* "ArrayExpression" */ + var elements: Array +} + +external interface ObjectExpression : BaseExpression { + override var type: String /* "ObjectExpression" */ + var properties: Array +} + +external interface Property : BaseNode { + override var type: String /* "Property" */ + var key: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var value: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern */ + get() = definedExternally + set(value) = definedExternally + var kind: String /* "init" | "get" | "set" */ + var method: Boolean + var shorthand: Boolean + var computed: Boolean +} + +external interface FunctionExpression : BaseFunction, BaseExpression { + var id: Identifier? + get() = definedExternally + set(value) = definedExternally + override var type: String /* "FunctionExpression" */ + override var body: BlockStatement +} + +external interface SequenceExpression : BaseExpression { + override var type: String /* "SequenceExpression" */ + var expressions: Array +} + +external interface UnaryExpression : BaseExpression { + override var type: String /* "UnaryExpression" */ + var operator: String /* "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" */ + var prefix: Boolean + var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BinaryExpression : BaseExpression { + override var type: String /* "BinaryExpression" */ + var operator: String /* "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "in" | "instanceof" */ + var left: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var right: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface AssignmentExpression : BaseExpression { + override var type: String /* "AssignmentExpression" */ + var operator: String /* "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" */ + var left: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ + get() = definedExternally + set(value) = definedExternally + var right: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface UpdateExpression : BaseExpression { + override var type: String /* "UpdateExpression" */ + var operator: String /* "++" | "--" */ + var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var prefix: Boolean +} + +external interface LogicalExpression : BaseExpression { + override var type: String /* "LogicalExpression" */ + var operator: String /* "||" | "&&" | "??" */ + var left: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var right: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalExpression : BaseExpression { + override var type: String /* "ConditionalExpression" */ + var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var alternate: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var consequent: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseCallExpression : BaseExpression { + var callee: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression | Super */ + get() = definedExternally + set(value) = definedExternally + var arguments: Array +} + +external interface SimpleCallExpression : BaseCallExpression { + override var type: String /* "CallExpression" */ + var optional: Boolean +} + +external interface NewExpression : BaseCallExpression { + override var type: String /* "NewExpression" */ +} + +external interface MemberExpression : BaseExpression, BasePattern { + override var type: String /* "MemberExpression" */ + var `object`: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression | Super */ + get() = definedExternally + set(value) = definedExternally + var property: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var computed: Boolean + var optional: Boolean +} + +external interface BasePattern : BaseNode + +external interface SwitchCase : BaseNode { + override var type: String /* "SwitchCase" */ + var test: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally + var consequent: Array +} + +external interface CatchClause : BaseNode { + override var type: String /* "CatchClause" */ + var param: dynamic /* Identifier? | ObjectPattern? | ArrayPattern? | RestElement? | AssignmentPattern? | MemberExpression? */ + get() = definedExternally + set(value) = definedExternally + var body: BlockStatement +} + +external interface Identifier : BaseNode, BaseExpression, BasePattern { + override var type: String /* "Identifier" */ + var name: String +} + +external interface SimpleLiteral : BaseNode, BaseExpression { + override var type: String /* "Literal" */ + var value: dynamic /* String? | Boolean? | Number? */ + get() = definedExternally + set(value) = definedExternally + var raw: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$1` { + var pattern: String + var flags: String +} + +external interface RegExpLiteral : BaseNode, BaseExpression { + override var type: String /* "Literal" */ + var value: RegExp? + get() = definedExternally + set(value) = definedExternally + var regex: `T$1` + var raw: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ForOfStatement : BaseForXStatement { + override var type: String /* "ForOfStatement" */ + var await: Boolean +} + +external interface Super : BaseNode { + override var type: String /* "Super" */ +} + +external interface SpreadElement : BaseNode { + override var type: String /* "SpreadElement" */ + var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ArrowFunctionExpression : BaseExpression, BaseFunction { + override var type: String /* "ArrowFunctionExpression" */ + var expression: Boolean + override var body: dynamic /* BlockStatement | ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface YieldExpression : BaseExpression { + override var type: String /* "YieldExpression" */ + var argument: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally + var delegate: Boolean +} + +external interface TemplateLiteral : BaseExpression { + override var type: String /* "TemplateLiteral" */ + var quasis: Array + var expressions: Array +} + +external interface TaggedTemplateExpression : BaseExpression { + override var type: String /* "TaggedTemplateExpression" */ + var tag: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var quasi: TemplateLiteral +} + +external interface `T$2` { + var cooked: String + var raw: String +} + +external interface TemplateElement : BaseNode { + override var type: String /* "TemplateElement" */ + var tail: Boolean + var value: `T$2` +} + +external interface AssignmentProperty : Property { + override var value: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ + get() = definedExternally + set(value) = definedExternally + override var kind: String /* "init" */ + override var method: Boolean +} + +external interface ObjectPattern : BasePattern { + override var type: String /* "ObjectPattern" */ + var properties: Array +} + +external interface ArrayPattern : BasePattern { + override var type: String /* "ArrayPattern" */ + var elements: Array +} + +external interface RestElement : BasePattern { + override var type: String /* "RestElement" */ + var argument: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface AssignmentPattern : BasePattern { + override var type: String /* "AssignmentPattern" */ + var left: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ + get() = definedExternally + set(value) = definedExternally + var right: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseClass : BaseNode { + var superClass: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ + get() = definedExternally + set(value) = definedExternally + var body: ClassBody +} + +external interface ClassBody : BaseNode { + override var type: String /* "ClassBody" */ + var body: Array +} + +external interface MethodDefinition : BaseNode { + override var type: String /* "MethodDefinition" */ + var key: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally + var value: FunctionExpression + var kind: String /* "constructor" | "method" | "get" | "set" */ + var computed: Boolean + var static: Boolean +} + +external interface ClassDeclaration : BaseClass, BaseDeclaration { + override var type: String /* "ClassDeclaration" */ + var id: Identifier? +} + +external interface ClassExpression : BaseClass, BaseExpression { + override var type: String /* "ClassExpression" */ + var id: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface MetaProperty : BaseExpression { + override var type: String /* "MetaProperty" */ + var meta: Identifier + var property: Identifier +} + +external interface BaseModuleDeclaration : BaseNode + +external interface BaseModuleSpecifier : BaseNode { + var local: Identifier +} + +external interface ImportDeclaration : BaseModuleDeclaration { + override var type: String /* "ImportDeclaration" */ + var specifiers: Array + var source: dynamic /* SimpleLiteral | RegExpLiteral */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ImportSpecifier : BaseModuleSpecifier { + override var type: String /* "ImportSpecifier" */ + var imported: Identifier +} + +external interface ImportExpression : BaseExpression { + override var type: String /* "ImportExpression" */ + var source: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ImportDefaultSpecifier : BaseModuleSpecifier { + override var type: String /* "ImportDefaultSpecifier" */ +} + +external interface ImportNamespaceSpecifier : BaseModuleSpecifier { + override var type: String /* "ImportNamespaceSpecifier" */ +} + +external interface ExportNamedDeclaration : BaseModuleDeclaration { + override var type: String /* "ExportNamedDeclaration" */ + var declaration: dynamic /* FunctionDeclaration? | VariableDeclaration? | ClassDeclaration? */ + get() = definedExternally + set(value) = definedExternally + var specifiers: Array + var source: dynamic /* SimpleLiteral? | RegExpLiteral? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ExportSpecifier : BaseModuleSpecifier { + override var type: String /* "ExportSpecifier" */ + var exported: Identifier +} + +external interface ExportDefaultDeclaration : BaseModuleDeclaration { + override var type: String /* "ExportDefaultDeclaration" */ + var declaration: dynamic /* FunctionDeclaration | VariableDeclaration | ClassDeclaration | ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ExportAllDeclaration : BaseModuleDeclaration { + override var type: String /* "ExportAllDeclaration" */ + var source: dynamic /* SimpleLiteral | RegExpLiteral */ + get() = definedExternally + set(value) = definedExternally +} + +external interface AwaitExpression : BaseExpression { + override var type: String /* "AwaitExpression" */ + var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt b/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt new file mode 100644 index 000000000..fd548b72b --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt @@ -0,0 +1,40 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +external interface IteratorReturnResult { + var done: Boolean + var value: TReturn +} + +external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +typealias Iterator__1 = Iterator + +external interface Iterable + +external interface IterableIterator : Iterator__1 \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/lib.es5.kt b/kmath-ast/src/jsMain/kotlin/lib.es5.kt new file mode 100644 index 000000000..fe3847232 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/lib.es5.kt @@ -0,0 +1,86 @@ +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "DEPRECATION", "PackageDirectoryMismatch", "KDocMissingDocumentation", + "PropertyName" +) + +package tsstdlib + +import kotlin.js.RegExp + +typealias RegExpMatchArray = Array + +typealias RegExpExecArray = Array + +external interface RegExpConstructor { + @nativeInvoke + operator fun invoke(pattern: RegExp, flags: String = definedExternally): RegExp + + @nativeInvoke + operator fun invoke(pattern: RegExp): RegExp + + @nativeInvoke + operator fun invoke(pattern: String, flags: String = definedExternally): RegExp + + @nativeInvoke + operator fun invoke(pattern: String): RegExp + var prototype: RegExp + var `$1`: String + var `$2`: String + var `$3`: String + var `$4`: String + var `$5`: String + var `$6`: String + var `$7`: String + var `$8`: String + var `$9`: String + var lastMatch: String +} + +external interface ConcatArray { + var length: Number + + @nativeGetter + operator fun get(n: Number): T? + + @nativeSetter + operator fun set(n: Number, value: T) + fun join(separator: String = definedExternally): String + fun slice(start: Number = definedExternally, end: Number = definedExternally): Array +} + +external interface ArrayConstructor { + fun from(iterable: Iterable): Array + fun from(iterable: ArrayLike): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array + fun of(vararg items: T): Array + + @nativeInvoke + operator fun invoke(arrayLength: Number = definedExternally): Array + + @nativeInvoke + operator fun invoke(): Array + + @nativeInvoke + operator fun invoke(arrayLength: Number): Array + + @nativeInvoke + operator fun invoke(vararg items: T): Array + fun isArray(arg: Any): Boolean + var prototype: Array +} + +external interface ArrayLike { + var length: Number + + @nativeGetter + operator fun get(n: Number): T? + + @nativeSetter + operator fun set(n: Number, value: T) +} + +typealias Extract = Any \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/stream.d.ts b/kmath-ast/src/jsMain/kotlin/stream.d.ts new file mode 100644 index 000000000..f98fcab8c --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/stream.d.ts @@ -0,0 +1,5 @@ +import {Emitter} from 'emitter' + +export class Stream extends Emitter { + pipe(dest: any, options: any): any +} diff --git a/kmath-ast/src/jsMain/kotlin/stream.kt b/kmath-ast/src/jsMain/kotlin/stream.kt new file mode 100644 index 000000000..d76f43f71 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/stream.kt @@ -0,0 +1,9 @@ +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "SortModifiers", + "KDocMissingDocumentation" +) + +external open class Stream : Emitter { + open fun pipe(dest: Any, options: Any): Any +} \ No newline at end of file From d66fb4be750e92c3f022e32be1338c743fdb1ac4 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 00:56:08 +0700 Subject: [PATCH 08/39] Delete empty file --- kmath-ast/src/jsMain/kotlin/Codegen.kt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 kmath-ast/src/jsMain/kotlin/Codegen.kt diff --git a/kmath-ast/src/jsMain/kotlin/Codegen.kt b/kmath-ast/src/jsMain/kotlin/Codegen.kt deleted file mode 100644 index e69de29bb..000000000 From 32d77c0e7f4868725c54d05fd99da783ffb8dec5 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 17:42:57 +0700 Subject: [PATCH 09/39] Implement ESTree based code generation for the MST --- kmath-ast/build.gradle.kts | 14 +++ kmath-ast/src/jsMain/kotlin/astring.global.kt | 2 +- kmath-ast/src/jsMain/kotlin/astring.kt | 16 +++- .../src/jsMain/kotlin/astring.typealises.kt | 3 + kmath-ast/src/jsMain/kotlin/emitter.d.ts | 3 - kmath-ast/src/jsMain/kotlin/emitter.kt | 5 +- .../src/jsMain/kotlin/estree.extensions.kt | 67 +++++++++++++ kmath-ast/src/jsMain/kotlin/estree.kt | 4 +- .../kotlin/kscience/kmath/estree/Codegen.kt | 78 +++++++++++++++ .../kmath/estree/internal/JSBuilder.kt | 73 ++++++++++++++ .../src/jsMain/kotlin/lib.es2015.iterable.kt | 18 +--- kmath-ast/src/jsMain/kotlin/stream.kt | 6 +- .../kmath/estree/TestESTreeAlgebras.kt | 94 +++++++++++++++++++ .../kmath/estree/TestESTreeExpressions.kt | 56 +++++++++++ .../kmath/estree/TestESTreeSpecialization.kt | 54 +++++++++++ .../kmath/estree/TestESTreeVariables.kt | 22 +++++ .../kscience/kmath/asm/internal/AsmBuilder.kt | 2 +- .../kscience/kmath/asm/TestAsmVariables.kt | 4 +- 18 files changed, 491 insertions(+), 30 deletions(-) create mode 100644 kmath-ast/src/jsMain/kotlin/astring.typealises.kt create mode 100644 kmath-ast/src/jsMain/kotlin/estree.extensions.kt create mode 100644 kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt create mode 100644 kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt create mode 100644 kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt create mode 100644 kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt create mode 100644 kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt create mode 100644 kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index e3884025d..1f4a87b12 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -2,6 +2,20 @@ plugins { id("ru.mipt.npm.mpp") } +kotlin.js { + nodejs { + testTask { + useMocha().timeout = "0" + } + } + + browser { + testTask { + useMocha().timeout = "0" + } + } +} + kotlin.sourceSets { commonMain { dependencies { diff --git a/kmath-ast/src/jsMain/kotlin/astring.global.kt b/kmath-ast/src/jsMain/kotlin/astring.global.kt index 78c771f26..c69c26caf 100644 --- a/kmath-ast/src/jsMain/kotlin/astring.global.kt +++ b/kmath-ast/src/jsMain/kotlin/astring.global.kt @@ -10,7 +10,7 @@ import Generator @Suppress("EXTERNAL_DELEGATION", "NESTED_CLASS_IN_EXTERNAL_INTERFACE") external interface astring { - var generate: Any + var generate: (dynamic, dynamic) -> dynamic var baseGenerator: Generator companion object : astring by definedExternally diff --git a/kmath-ast/src/jsMain/kotlin/astring.kt b/kmath-ast/src/jsMain/kotlin/astring.kt index e9ab6f627..fe2b2da0a 100644 --- a/kmath-ast/src/jsMain/kotlin/astring.kt +++ b/kmath-ast/src/jsMain/kotlin/astring.kt @@ -1,7 +1,15 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation" +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "PackageDirectoryMismatch" ) +@file:JsModule("astring") +@file:JsNonModule +package astring + +import Generator +import estree.BaseNode + external interface Options { var indent: String? get() = definedExternally @@ -27,6 +35,4 @@ external fun generate(node: BaseNode, options: Options /* Options & `T$0` */ = d external fun generate(node: BaseNode): String -typealias Generator = Any - -external var baseGenerator: Generator \ No newline at end of file +external var baseGenerator: Generator diff --git a/kmath-ast/src/jsMain/kotlin/astring.typealises.kt b/kmath-ast/src/jsMain/kotlin/astring.typealises.kt new file mode 100644 index 000000000..9b74e2d04 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/astring.typealises.kt @@ -0,0 +1,3 @@ +@file:Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation") + +typealias Generator = Any diff --git a/kmath-ast/src/jsMain/kotlin/emitter.d.ts b/kmath-ast/src/jsMain/kotlin/emitter.d.ts index ea0319cd6..4970529d4 100644 --- a/kmath-ast/src/jsMain/kotlin/emitter.d.ts +++ b/kmath-ast/src/jsMain/kotlin/emitter.d.ts @@ -14,6 +14,3 @@ export class Emitter { hasListeners(event: string): boolean } - - -function mixin(obj: any): any diff --git a/kmath-ast/src/jsMain/kotlin/emitter.kt b/kmath-ast/src/jsMain/kotlin/emitter.kt index ad0a16bf7..94398397f 100644 --- a/kmath-ast/src/jsMain/kotlin/emitter.kt +++ b/kmath-ast/src/jsMain/kotlin/emitter.kt @@ -2,9 +2,12 @@ "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", - "CONFLICTING_OVERLOADS", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "SortModifiers" + "CONFLICTING_OVERLOADS", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "SortModifiers", + "PackageDirectoryMismatch" ) +package emitter + external open class Emitter { constructor(obj: Any) constructor() diff --git a/kmath-ast/src/jsMain/kotlin/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/estree.extensions.kt new file mode 100644 index 000000000..d4fc4baa1 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/estree.extensions.kt @@ -0,0 +1,67 @@ +@file:Suppress( + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", + "NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING", "PackageDirectoryMismatch" +) + +package estree + +fun Program(sourceType: String, vararg body: dynamic) = object : Program { + override var type = "Program" + override var sourceType = sourceType + override var body = body +} + +fun VariableDeclaration(kind: String, vararg declarations: VariableDeclarator) = object : VariableDeclaration { + override var type = "VariableDeclaration" + override var declarations = declarations.toList().toTypedArray() + override var kind = kind +} + +fun VariableDeclarator(id: dynamic, init: dynamic) = object : VariableDeclarator { + override var type = "VariableDeclarator" + override var id = id + override var init = init +} + +fun Identifier(name: String) = object : Identifier { + override var type = "Identifier" + override var name = name +} + +fun FunctionExpression(params: Array, body: BlockStatement) = object : FunctionExpression { + override var params = params + override var type = "FunctionExpression" + override var body = body +} + +fun BlockStatement(vararg body: dynamic) = object : BlockStatement { + override var type = "BlockStatement" + override var body = body +} + +fun ReturnStatement(argument: dynamic) = object : ReturnStatement { + override var type = "ReturnStatement" + override var argument = argument +} + +fun SimpleLiteral(value: dynamic) = object : SimpleLiteral { + override var type = "Literal" + override var value = value +} + +fun MemberExpression(computed: Boolean, optional: Boolean, `object`: dynamic, property: dynamic) = + object : MemberExpression { + override var type = "MemberExpression" + override var computed = computed + override var optional = optional + override var `object` = `object` + override var property = property + } + +fun SimpleCallExpression(optional: Boolean, callee: dynamic, vararg arguments: dynamic) = + object : SimpleCallExpression { + override var type = "CallExpression" + override var optional = optional + override var callee = callee + override var arguments = arguments + } diff --git a/kmath-ast/src/jsMain/kotlin/estree.kt b/kmath-ast/src/jsMain/kotlin/estree.kt index 841688f6d..79d043eae 100644 --- a/kmath-ast/src/jsMain/kotlin/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/estree.kt @@ -1,8 +1,10 @@ @file:Suppress( "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "ClassName", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "ClassName", "PackageDirectoryMismatch", ) +package estree + import kotlin.js.RegExp external interface BaseNodeWithoutComments { diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt new file mode 100644 index 000000000..d10c9c0cf --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt @@ -0,0 +1,78 @@ +package kscience.kmath.estree + +import estree.* +import kscience.kmath.ast.MST +import kscience.kmath.ast.MstExpression +import kscience.kmath.estree.internal.JSBuilder +import kscience.kmath.expressions.Expression +import kscience.kmath.operations.Algebra +import kscience.kmath.operations.NumericAlgebra +import kscience.kmath.operations.RealField + +@PublishedApi +internal fun MST.compileWith(algebra: Algebra): Expression { + fun JSBuilder.visit(node: MST): BaseExpression = when (node) { + is MST.Symbolic -> { + val symbol = try { + algebra.symbol(node.value) + } catch (ignored: IllegalStateException) { + null + } + + if (symbol != null) + constant(symbol) + else + variable(node.value) + } + + is MST.Numeric -> constant(node.value) + is MST.Unary -> call(algebra.unaryOperation(node.operation), visit(node.value)) + + is MST.Binary -> when { + algebra is NumericAlgebra && node.left is MST.Numeric && node.right is MST.Numeric -> constant( + algebra.number( + RealField + .binaryOperation(node.operation) + .invoke(node.left.value.toDouble(), node.right.value.toDouble()) + ) + ) + + algebra is NumericAlgebra && node.left is MST.Numeric -> call( + algebra.leftSideNumberOperation(node.operation), + visit(node.left), + visit(node.right), + ) + + algebra is NumericAlgebra && node.right is MST.Numeric -> call( + algebra.rightSideNumberOperation(node.operation), + visit(node.left), + visit(node.right), + ) + + else -> call( + algebra.binaryOperation(node.operation), + visit(node.left), + visit(node.right), + ) + } + } + + return JSBuilder { visit(this@compileWith) }.instance +} + + +/** + * Compiles an [MST] to ASM using given algebra. + * + * @author Alexander Nozik. + */ +public fun Algebra.expression(mst: MST): Expression = + mst.compileWith(this) + +/** + * Optimizes performance of an [MstExpression] using ASM codegen. + * + * @author Alexander Nozik. + */ +public fun MstExpression>.compile(): Expression = + mst.compileWith(algebra) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt new file mode 100644 index 000000000..7b3f02616 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -0,0 +1,73 @@ +package kscience.kmath.estree.internal + +import astring.generate +import estree.* +import kscience.kmath.expressions.Expression +import kscience.kmath.expressions.Symbol + +internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) { + private class GeneratedExpression(val executable: dynamic, val constants: Array) : Expression { + @Suppress("UNUSED_VARIABLE", "PARAMETER_NAME_CHANGED_ON_OVERRIDE") + override fun invoke(map: Map): T { + val e = executable + val c = constants + val a = js("{}") + map.forEach { (key, value) -> a[key.identity] = value } + return js("e(c, a)").unsafeCast() + } + } + + val instance: Expression by lazy { + val node = Program( + sourceType = "script", + VariableDeclaration( + kind = "var", + VariableDeclarator( + id = Identifier("executable"), + init = FunctionExpression( + params = arrayOf(Identifier("constants"), Identifier("arguments")), + body = BlockStatement(ReturnStatement(bodyCallback())), + ), + ), + ), + ) + + eval(generate(node)) + GeneratedExpression(js("executable"), constants.toTypedArray()) + } + + private val constants = mutableListOf() + private val keys = mutableListOf() + + fun constant(value: Any?) = when { + value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" -> { + SimpleLiteral(value) + } + + else -> { + val idx = if (value in constants) constants.indexOf(value) else constants.also { it += value }.lastIndex + + MemberExpression( + computed = true, + optional = false, + `object` = Identifier("constants"),я + property = SimpleLiteral(idx), + ) + } + } + + fun variable(name: String): BaseExpression { + return MemberExpression( + computed = true, + optional = false, + `object` = Identifier("arguments"), + property = SimpleLiteral(name), + ) + } + + fun call(function: Function, vararg args: BaseExpression): BaseExpression = SimpleCallExpression( + optional = false, + callee = constant(function), + *args, + ) +} diff --git a/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt b/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt index fd548b72b..b55785a8e 100644 --- a/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt +++ b/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt @@ -1,20 +1,8 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", + "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "PackageDirectoryMismatch" +) package tsstdlib -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - external interface IteratorYieldResult { var done: Boolean? get() = definedExternally diff --git a/kmath-ast/src/jsMain/kotlin/stream.kt b/kmath-ast/src/jsMain/kotlin/stream.kt index d76f43f71..c6c30446c 100644 --- a/kmath-ast/src/jsMain/kotlin/stream.kt +++ b/kmath-ast/src/jsMain/kotlin/stream.kt @@ -1,9 +1,13 @@ @file:Suppress( "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "SortModifiers", - "KDocMissingDocumentation" + "KDocMissingDocumentation", "PackageDirectoryMismatch" ) +package stream + +import emitter.Emitter + external open class Stream : Emitter { open fun pipe(dest: Any, options: Any): Any } \ No newline at end of file diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt new file mode 100644 index 000000000..09a8ab3e5 --- /dev/null +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt @@ -0,0 +1,94 @@ +package kscience.kmath.estree + +import kscience.kmath.ast.mstInField +import kscience.kmath.ast.mstInRing +import kscience.kmath.ast.mstInSpace +import kscience.kmath.expressions.invoke +import kscience.kmath.operations.ByteRing +import kscience.kmath.operations.RealField +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class TestESTreeAlgebras { + @Test + fun space() { + val res1 = ByteRing.mstInSpace { + binaryOperation("+")( + unaryOperation("+")( + number(3.toByte()) - (number(2.toByte()) + (multiply( + add(number(1), number(1)), + 2 + ) + number(1.toByte()) * 3.toByte() - number(1.toByte()))) + ), + + number(1) + ) + symbol("x") + zero + }("x" to 2.toByte()) + + val res2 = ByteRing.mstInSpace { + binaryOperation("+")( + unaryOperation("+")( + number(3.toByte()) - (number(2.toByte()) + (multiply( + add(number(1), number(1)), + 2 + ) + number(1.toByte()) * 3.toByte() - number(1.toByte()))) + ), + + number(1) + ) + symbol("x") + zero + }.compile()("x" to 2.toByte()) + + assertEquals(res1, res2) + } + + @Test + fun ring() { + val res1 = ByteRing.mstInRing { + binaryOperation("+")( + unaryOperation("+")( + (symbol("x") - (2.toByte() + (multiply( + add(number(1), number(1)), + 2 + ) + 1.toByte()))) * 3.0 - 1.toByte() + ), + + number(1) + ) * number(2) + }("x" to 3.toByte()) + + val res2 = ByteRing.mstInRing { + binaryOperation("+")( + unaryOperation("+")( + (symbol("x") - (2.toByte() + (multiply( + add(number(1), number(1)), + 2 + ) + 1.toByte()))) * 3.0 - 1.toByte() + ), + number(1) + ) * number(2) + }.compile()("x" to 3.toByte()) + + assertEquals(res1, res2) + } + + @Test + fun field() { + val res1 = RealField.mstInField { + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + + number(1), + number(1) / 2 + number(2.0) * one + ) + zero + }("x" to 2.0) + + val res2 = RealField.mstInField { + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + + number(1), + number(1) / 2 + number(2.0) * one + ) + zero + }.compile()("x" to 2.0) + + assertEquals(res1, res2) + } +} diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt new file mode 100644 index 000000000..3dc259cb3 --- /dev/null +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt @@ -0,0 +1,56 @@ +package kscience.kmath.estree + +import kscience.kmath.ast.mstInExtendedField +import kscience.kmath.ast.mstInField +import kscience.kmath.ast.mstInSpace +import kscience.kmath.expressions.Expression +import kscience.kmath.expressions.StringSymbol +import kscience.kmath.expressions.invoke +import kscience.kmath.operations.RealField +import kotlin.math.pow +import kotlin.random.Random +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.time.measureTime + +internal class TestESTreeExpressions { + @Test + fun testUnaryOperationInvocation() { + val expression = RealField.mstInSpace { -symbol("x") }.compile() + val res = expression("x" to 2.0) + assertEquals(-2.0, res) + } + + @Test + fun testBinaryOperationInvocation() { + val expression = RealField.mstInSpace { -symbol("x") + number(1.0) }.compile() + val res = expression("x" to 2.0) + assertEquals(-1.0, res) + } + + @Test + fun testConstProductInvocation() { + val res = RealField.mstInField { symbol("x") * 2 }("x" to 2.0) + assertEquals(4.0, res) + } + + @Test + fun testMultipleCalls() { + val e1 = + RealField.mstInExtendedField { sin(symbol("x")).pow(4) - 6 * symbol("x") / tanh(symbol("x")) }.compile() + + val e2 = Expression { a -> + val x = a.getValue(StringSymbol("x")) + kotlin.math.sin(x).pow(4) - 6 * x / kotlin.math.tanh(x) + } + + var r = Random(0) + var s = 0.0 + measureTime { repeat(1000000) { s += e1("x" to r.nextDouble()) } }.also(::println) + println(s) + s = 0.0 + r = Random(0) + measureTime { repeat(1000000) { s += e2("x" to r.nextDouble()) } }.also(::println) + println(s) + } +} diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt new file mode 100644 index 000000000..0821686fc --- /dev/null +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt @@ -0,0 +1,54 @@ +package kscience.kmath.estree + +import kscience.kmath.ast.mstInField +import kscience.kmath.expressions.invoke +import kscience.kmath.operations.RealField +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class TestESTreeSpecialization { + @Test + fun testUnaryPlus() { + val expr = RealField.mstInField { unaryOperation("+")(symbol("x")) }.compile() + assertEquals(2.0, expr("x" to 2.0)) + } + + @Test + fun testUnaryMinus() { + val expr = RealField.mstInField { unaryOperation("-")(symbol("x")) }.compile() + assertEquals(-2.0, expr("x" to 2.0)) + } + + @Test + fun testAdd() { + val expr = RealField.mstInField { binaryOperation("+")(symbol("x"), symbol("x")) }.compile() + assertEquals(4.0, expr("x" to 2.0)) + } + + @Test + fun testSine() { + val expr = RealField.mstInField { unaryOperation("sin")(symbol("x")) }.compile() + assertEquals(0.0, expr("x" to 0.0)) + } + + @Test + fun testMinus() { + val expr = RealField.mstInField { binaryOperation("-")(symbol("x"), symbol("x")) }.compile() + assertEquals(0.0, expr("x" to 2.0)) + } + + @Test + fun testDivide() { + val expr = RealField.mstInField { binaryOperation("/")(symbol("x"), symbol("x")) }.compile() + assertEquals(1.0, expr("x" to 2.0)) + } + + @Test + fun testPower() { + val expr = RealField + .mstInField { binaryOperation("pow")(symbol("x"), number(2)) } + .compile() + + assertEquals(4.0, expr("x" to 2.0)) + } +} diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt new file mode 100644 index 000000000..b6f59247d --- /dev/null +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt @@ -0,0 +1,22 @@ +package kscience.kmath.estree + +import kscience.kmath.ast.mstInRing +import kscience.kmath.expressions.invoke +import kscience.kmath.operations.ByteRing +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + +internal class TestESTreeVariables { + @Test + fun testVariableWithoutDefault() { + val expr = ByteRing.mstInRing { symbol("x") }.compile() + assertEquals(1.toByte(), expr("x" to 1.toByte())) + } + + @Test + fun testVariableWithoutDefaultFails() { + val expr = ByteRing.mstInRing { symbol("x") }.compile() + assertFailsWith { expr() } + } +} diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index d146afeee..20e42ed25 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -274,7 +274,7 @@ internal class AsmBuilder( inline fun buildCall(function: Function, parameters: AsmBuilder.() -> Unit) { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) } - val `interface` = function.javaClass.interfaces.first { it.interfaces.contains(Function::class.java) } + val `interface` = function.javaClass.interfaces.first { Function::class.java in it.interfaces } val arity = `interface`.methods.find { it.name == "invoke" }?.parameterCount ?: error("Provided function object doesn't contain invoke method") diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt index 1011515c8..0ebc31be4 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt @@ -10,13 +10,13 @@ import kotlin.test.assertFailsWith internal class TestAsmVariables { @Test fun testVariableWithoutDefault() { - val expr = ByteRing.mstInRing { symbol("x") } + val expr = ByteRing.mstInRing { symbol("x") }.compile() assertEquals(1.toByte(), expr("x" to 1.toByte())) } @Test fun testVariableWithoutDefaultFails() { - val expr = ByteRing.mstInRing { symbol("x") } + val expr = ByteRing.mstInRing { symbol("x") }.compile() assertFailsWith { expr() } } } From a655404486d5cebef9e8c52c2a0c0e69e394dda3 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 17:43:21 +0700 Subject: [PATCH 10/39] Fix typo --- .../jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt index 7b3f02616..b6b58179b 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -50,7 +50,7 @@ internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) MemberExpression( computed = true, optional = false, - `object` = Identifier("constants"),я + `object` = Identifier("constants"), property = SimpleLiteral(idx), ) } From 484b35cb4fcb363053512baf3e619410d8ba03cc Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 18:34:35 +0700 Subject: [PATCH 11/39] Fix failing tests --- .../kmath/estree/internal/JSBuilder.kt | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt index b6b58179b..c77f0c9ef 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -56,18 +56,25 @@ internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) } } - fun variable(name: String): BaseExpression { - return MemberExpression( - computed = true, - optional = false, - `object` = Identifier("arguments"), - property = SimpleLiteral(name), - ) - } + fun variable(name: String): BaseExpression = call(getOrFail, Identifier("arguments"), SimpleLiteral(name)) fun call(function: Function, vararg args: BaseExpression): BaseExpression = SimpleCallExpression( optional = false, callee = constant(function), *args, ) + + private companion object { + @Suppress("UNUSED_VARIABLE") + val getOrFail: (`object`: dynamic, key: String) -> dynamic = { `object`, key -> + val k = key + val o = `object` + + if (!(js("k in o") as Boolean)) { + throw NoSuchElementException() + } + + js("o[k]") + } + } } From 3cd00b9df60343767b81d5116196b441cbb5207a Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 18:55:59 +0700 Subject: [PATCH 12/39] Inline internal functions with one usage --- .../kscience/kmath/asm/internal/AsmBuilder.kt | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index 20e42ed25..882b95bf0 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -204,18 +204,13 @@ internal class AsmBuilder( */ fun loadObjectConstant(value: Any, type: Type = tType): Unit = invokeMethodVisitor.run { val idx = if (value in constants) constants.indexOf(value) else constants.also { it += value }.lastIndex - loadThis() + invokeMethodVisitor.load(0, classType) getfield(classType.internalName, "constants", OBJECT_ARRAY_TYPE.descriptor) iconst(idx) visitInsn(AALOAD) if (type != OBJECT_TYPE) checkcast(type) } - /** - * Loads `this` variable. - */ - private fun loadThis(): Unit = invokeMethodVisitor.load(0, classType) - /** * Either loads a numeric constant [value] from the class's constants field or boxes a primitive * constant from the constant pool. @@ -234,27 +229,21 @@ internal class AsmBuilder( SHORT_TYPE -> invokeMethodVisitor.iconst(value.toInt()) } - box(primitive) + val r = PRIMITIVES_TO_BOXED.getValue(primitive) + + invokeMethodVisitor.invokestatic( + r.internalName, + "valueOf", + getMethodDescriptor(r, primitive), + false, + ) + return } loadObjectConstant(value, boxed) } - /** - * Boxes the current value and pushes it. - */ - private fun box(primitive: Type) { - val r = PRIMITIVES_TO_BOXED.getValue(primitive) - - invokeMethodVisitor.invokestatic( - r.internalName, - "valueOf", - getMethodDescriptor(r, primitive), - false, - ) - } - /** * Loads a variable [name] from arguments [Map] parameter of [Expression.invoke]. */ From 95701bec1b36759242f2c05a06e8dc0ed01c0b8f Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 19:02:36 +0700 Subject: [PATCH 13/39] Add informative NoSuchElementException message --- .../kotlin/kscience/kmath/estree/internal/JSBuilder.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt index c77f0c9ef..c6a36b538 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -70,9 +70,8 @@ internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) val k = key val o = `object` - if (!(js("k in o") as Boolean)) { - throw NoSuchElementException() - } + if (!(js("k in o") as Boolean)) + throw NoSuchElementException("Key $key is missing in the map.") js("o[k]") } From 9a875bc7db3a3e1b5707c2cfdc4dfaec048bc1b2 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 19:04:09 +0700 Subject: [PATCH 14/39] Add missing newline --- kmath-ast/src/jsMain/kotlin/astring.global.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-ast/src/jsMain/kotlin/astring.global.kt b/kmath-ast/src/jsMain/kotlin/astring.global.kt index c69c26caf..d8514c310 100644 --- a/kmath-ast/src/jsMain/kotlin/astring.global.kt +++ b/kmath-ast/src/jsMain/kotlin/astring.global.kt @@ -14,4 +14,4 @@ external interface astring { var baseGenerator: Generator companion object : astring by definedExternally -} \ No newline at end of file +} From d9932042e84ccd1b36274619225fd9fcb5f390ff Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 19:04:43 +0700 Subject: [PATCH 15/39] Delete TS bindings --- kmath-ast/src/jsMain/kotlin/astring.d.ts | 50 -- kmath-ast/src/jsMain/kotlin/emitter.d.ts | 16 - kmath-ast/src/jsMain/kotlin/estree.d.ts | 569 ----------------------- kmath-ast/src/jsMain/kotlin/stream.d.ts | 5 - 4 files changed, 640 deletions(-) delete mode 100644 kmath-ast/src/jsMain/kotlin/astring.d.ts delete mode 100644 kmath-ast/src/jsMain/kotlin/emitter.d.ts delete mode 100644 kmath-ast/src/jsMain/kotlin/estree.d.ts delete mode 100644 kmath-ast/src/jsMain/kotlin/stream.d.ts diff --git a/kmath-ast/src/jsMain/kotlin/astring.d.ts b/kmath-ast/src/jsMain/kotlin/astring.d.ts deleted file mode 100644 index 22cd7e980..000000000 --- a/kmath-ast/src/jsMain/kotlin/astring.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Type definitions for astring 1.3 -// Project: https://github.com/davidbonnet/astring -// Definitions by: Nikolaj Kappler -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.8 - -import * as ESTree from 'estree'; -import 'node'; -import { Stream } from 'stream'; - -export interface Options { - /** string to use for indentation (defaults to " ") */ - indent?: string; - /** string to use for line endings (defaults to "\n") */ - lineEnd?: string; - /** indent level to start from (defaults to 0) */ - startingIndentLevel?: number; - /** generate comments if true (defaults to false) */ - comments?: boolean; - /** custom code generator (defaults to astring.baseGenerator) */ - generator?: object; - /** source map generator (defaults to null), see https://github.com/mozilla/source-map#sourcemapgenerator */ - sourceMap?: any; -} - -/** Returns a string representing the rendered code of the provided AST `node`. However, if an `output` stream is provided in the options, it writes to that stream and returns it. */ -export function generate(node: ESTree.Node, options?: Options): string; -/** Returns a string representing the rendered code of the provided AST `node`. However, if an `output` stream is provided in the options, it writes to that stream and returns it. */ -export function generate(node: ESTree.Node, options: Options & { - /** output stream to write the rendered code to (defaults to null) */ - output: Stream; -}): Stream; - -/** - * A code generator consists of a mapping of node names and functions that take two arguments: `node` and `state`. - * The `node` points to the node from which to generate the code and the `state` exposes the `write` method that takes generated code strings. - */ -export type Generator = { [key in ESTree.Node["type"]]: (node: Extract, state: { write(s: string): void }) => void }; - -/** Base generator that can be used to extend Astring. See https://github.com/davidbonnet/astring#extending */ -export const baseGenerator: Generator; - -declare global { - interface astring { - generate: typeof generate; - /** Base generator that can be used to extend Astring. See https://github.com/davidbonnet/astring#extending */ - baseGenerator: Generator; - } - const astring: astring; -} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/emitter.d.ts b/kmath-ast/src/jsMain/kotlin/emitter.d.ts deleted file mode 100644 index 4970529d4..000000000 --- a/kmath-ast/src/jsMain/kotlin/emitter.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -export class Emitter { - constructor(obj: any) - constructor() - - on(event: string, fn: () => void) - - off(event: string, fn: () => void) - - once(event: string, fn: () => void) - - emit(event: string, ...any: any[]) - - listeners(event: string): (() => void)[] - - hasListeners(event: string): boolean -} diff --git a/kmath-ast/src/jsMain/kotlin/estree.d.ts b/kmath-ast/src/jsMain/kotlin/estree.d.ts deleted file mode 100644 index 927477c66..000000000 --- a/kmath-ast/src/jsMain/kotlin/estree.d.ts +++ /dev/null @@ -1,569 +0,0 @@ -// Type definitions for ESTree AST specification -// Project: https://github.com/estree/estree -// Definitions by: RReverser -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -// This definition file follows a somewhat unusual format. ESTree allows -// runtime type checks based on the `type` parameter. In order to explain this -// to typescript we want to use discriminated union types: -// https://github.com/Microsoft/TypeScript/pull/9163 -// -// For ESTree this is a bit tricky because the high level interfaces like -// Node or Function are pulling double duty. We want to pass common fields down -// to the interfaces that extend them (like Identifier or -// ArrowFunctionExpression), but you can't extend a type union or enforce -// common fields on them. So we've split the high level interfaces into two -// types, a base type which passes down inhereted fields, and a type union of -// all types which extend the base type. Only the type union is exported, and -// the union is how other types refer to the collection of inheriting types. -// -// This makes the definitions file here somewhat more difficult to maintain, -// but it has the notable advantage of making ESTree much easier to use as -// an end user. - -interface BaseNodeWithoutComments { - // Every leaf interface that extends BaseNode must specify a type property. - // The type property should be a string literal. For example, Identifier - // has: `type: "Identifier"` - type: string; - loc?: SourceLocation | null; - range?: [number, number]; -} - -interface BaseNode extends BaseNodeWithoutComments { - leadingComments?: Array; - trailingComments?: Array; -} - -export type Node = - Identifier | Literal | Program | Function | SwitchCase | CatchClause | - VariableDeclarator | Statement | Expression | Property | - AssignmentProperty | Super | TemplateElement | SpreadElement | Pattern | - ClassBody | Class | MethodDefinition | ModuleDeclaration | ModuleSpecifier; - -export interface Comment extends BaseNodeWithoutComments { - type: "Line" | "Block"; - value: string; -} - -interface SourceLocation { - source?: string | null; - start: Position; - end: Position; -} - -export interface Position { - /** >= 1 */ - line: number; - /** >= 0 */ - column: number; -} - -export interface Program extends BaseNode { - type: "Program"; - sourceType: "script" | "module"; - body: Array; - comments?: Array; -} - -export interface Directive extends BaseNode { - type: "ExpressionStatement"; - expression: Literal; - directive: string; -} - -interface BaseFunction extends BaseNode { - params: Array; - generator?: boolean; - async?: boolean; - // The body is either BlockStatement or Expression because arrow functions - // can have a body that's either. FunctionDeclarations and - // FunctionExpressions have only BlockStatement bodies. - body: BlockStatement | Expression; -} - -export type Function = - FunctionDeclaration | FunctionExpression | ArrowFunctionExpression; - -export type Statement = - ExpressionStatement | BlockStatement | EmptyStatement | - DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | - BreakStatement | ContinueStatement | IfStatement | SwitchStatement | - ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | - ForStatement | ForInStatement | ForOfStatement | Declaration; - -interface BaseStatement extends BaseNode { } - -export interface EmptyStatement extends BaseStatement { - type: "EmptyStatement"; -} - -export interface BlockStatement extends BaseStatement { - type: "BlockStatement"; - body: Array; - innerComments?: Array; -} - -export interface ExpressionStatement extends BaseStatement { - type: "ExpressionStatement"; - expression: Expression; -} - -export interface IfStatement extends BaseStatement { - type: "IfStatement"; - test: Expression; - consequent: Statement; - alternate?: Statement | null; -} - -export interface LabeledStatement extends BaseStatement { - type: "LabeledStatement"; - label: Identifier; - body: Statement; -} - -export interface BreakStatement extends BaseStatement { - type: "BreakStatement"; - label?: Identifier | null; -} - -export interface ContinueStatement extends BaseStatement { - type: "ContinueStatement"; - label?: Identifier | null; -} - -export interface WithStatement extends BaseStatement { - type: "WithStatement"; - object: Expression; - body: Statement; -} - -export interface SwitchStatement extends BaseStatement { - type: "SwitchStatement"; - discriminant: Expression; - cases: Array; -} - -export interface ReturnStatement extends BaseStatement { - type: "ReturnStatement"; - argument?: Expression | null; -} - -export interface ThrowStatement extends BaseStatement { - type: "ThrowStatement"; - argument: Expression; -} - -export interface TryStatement extends BaseStatement { - type: "TryStatement"; - block: BlockStatement; - handler?: CatchClause | null; - finalizer?: BlockStatement | null; -} - -export interface WhileStatement extends BaseStatement { - type: "WhileStatement"; - test: Expression; - body: Statement; -} - -export interface DoWhileStatement extends BaseStatement { - type: "DoWhileStatement"; - body: Statement; - test: Expression; -} - -export interface ForStatement extends BaseStatement { - type: "ForStatement"; - init?: VariableDeclaration | Expression | null; - test?: Expression | null; - update?: Expression | null; - body: Statement; -} - -interface BaseForXStatement extends BaseStatement { - left: VariableDeclaration | Pattern; - right: Expression; - body: Statement; -} - -export interface ForInStatement extends BaseForXStatement { - type: "ForInStatement"; -} - -export interface DebuggerStatement extends BaseStatement { - type: "DebuggerStatement"; -} - -export type Declaration = - FunctionDeclaration | VariableDeclaration | ClassDeclaration; - -interface BaseDeclaration extends BaseStatement { } - -export interface FunctionDeclaration extends BaseFunction, BaseDeclaration { - type: "FunctionDeclaration"; - /** It is null when a function declaration is a part of the `export default function` statement */ - id: Identifier | null; - body: BlockStatement; -} - -export interface VariableDeclaration extends BaseDeclaration { - type: "VariableDeclaration"; - declarations: Array; - kind: "var" | "let" | "const"; -} - -export interface VariableDeclarator extends BaseNode { - type: "VariableDeclarator"; - id: Pattern; - init?: Expression | null; -} - -type Expression = - ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | - ArrowFunctionExpression | YieldExpression | Literal | UnaryExpression | - UpdateExpression | BinaryExpression | AssignmentExpression | - LogicalExpression | MemberExpression | ConditionalExpression | - CallExpression | NewExpression | SequenceExpression | TemplateLiteral | - TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | - AwaitExpression | ImportExpression | ChainExpression; - -export interface BaseExpression extends BaseNode { } - -type ChainElement = SimpleCallExpression | MemberExpression; - -export interface ChainExpression extends BaseExpression { - type: "ChainExpression"; - expression: ChainElement; -} - -export interface ThisExpression extends BaseExpression { - type: "ThisExpression"; -} - -export interface ArrayExpression extends BaseExpression { - type: "ArrayExpression"; - elements: Array; -} - -export interface ObjectExpression extends BaseExpression { - type: "ObjectExpression"; - properties: Array; -} - -export interface Property extends BaseNode { - type: "Property"; - key: Expression; - value: Expression | Pattern; // Could be an AssignmentProperty - kind: "init" | "get" | "set"; - method: boolean; - shorthand: boolean; - computed: boolean; -} - -export interface FunctionExpression extends BaseFunction, BaseExpression { - id?: Identifier | null; - type: "FunctionExpression"; - body: BlockStatement; -} - -export interface SequenceExpression extends BaseExpression { - type: "SequenceExpression"; - expressions: Array; -} - -export interface UnaryExpression extends BaseExpression { - type: "UnaryExpression"; - operator: UnaryOperator; - prefix: true; - argument: Expression; -} - -export interface BinaryExpression extends BaseExpression { - type: "BinaryExpression"; - operator: BinaryOperator; - left: Expression; - right: Expression; -} - -export interface AssignmentExpression extends BaseExpression { - type: "AssignmentExpression"; - operator: AssignmentOperator; - left: Pattern | MemberExpression; - right: Expression; -} - -export interface UpdateExpression extends BaseExpression { - type: "UpdateExpression"; - operator: UpdateOperator; - argument: Expression; - prefix: boolean; -} - -export interface LogicalExpression extends BaseExpression { - type: "LogicalExpression"; - operator: LogicalOperator; - left: Expression; - right: Expression; -} - -export interface ConditionalExpression extends BaseExpression { - type: "ConditionalExpression"; - test: Expression; - alternate: Expression; - consequent: Expression; -} - -interface BaseCallExpression extends BaseExpression { - callee: Expression | Super; - arguments: Array; -} -export type CallExpression = SimpleCallExpression | NewExpression; - -export interface SimpleCallExpression extends BaseCallExpression { - type: "CallExpression"; - optional: boolean; -} - -export interface NewExpression extends BaseCallExpression { - type: "NewExpression"; -} - -export interface MemberExpression extends BaseExpression, BasePattern { - type: "MemberExpression"; - object: Expression | Super; - property: Expression; - computed: boolean; - optional: boolean; -} - -export type Pattern = - Identifier | ObjectPattern | ArrayPattern | RestElement | - AssignmentPattern | MemberExpression; - -interface BasePattern extends BaseNode { } - -export interface SwitchCase extends BaseNode { - type: "SwitchCase"; - test?: Expression | null; - consequent: Array; -} - -export interface CatchClause extends BaseNode { - type: "CatchClause"; - param: Pattern | null; - body: BlockStatement; -} - -export interface Identifier extends BaseNode, BaseExpression, BasePattern { - type: "Identifier"; - name: string; -} - -export type Literal = SimpleLiteral | RegExpLiteral; - -export interface SimpleLiteral extends BaseNode, BaseExpression { - type: "Literal"; - value: string | boolean | number | null; - raw?: string; -} - -export interface RegExpLiteral extends BaseNode, BaseExpression { - type: "Literal"; - value?: RegExp | null; - regex: { - pattern: string; - flags: string; - }; - raw?: string; -} - -export type UnaryOperator = - "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; - -export type BinaryOperator = - "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | - ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "in" | - "instanceof"; - -export type LogicalOperator = "||" | "&&" | "??"; - -export type AssignmentOperator = - "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "<<=" | ">>=" | ">>>=" | - "|=" | "^=" | "&="; - -export type UpdateOperator = "++" | "--"; - -export interface ForOfStatement extends BaseForXStatement { - type: "ForOfStatement"; - await: boolean; -} - -export interface Super extends BaseNode { - type: "Super"; -} - -export interface SpreadElement extends BaseNode { - type: "SpreadElement"; - argument: Expression; -} - -export interface ArrowFunctionExpression extends BaseExpression, BaseFunction { - type: "ArrowFunctionExpression"; - expression: boolean; - body: BlockStatement | Expression; -} - -export interface YieldExpression extends BaseExpression { - type: "YieldExpression"; - argument?: Expression | null; - delegate: boolean; -} - -export interface TemplateLiteral extends BaseExpression { - type: "TemplateLiteral"; - quasis: Array; - expressions: Array; -} - -export interface TaggedTemplateExpression extends BaseExpression { - type: "TaggedTemplateExpression"; - tag: Expression; - quasi: TemplateLiteral; -} - -export interface TemplateElement extends BaseNode { - type: "TemplateElement"; - tail: boolean; - value: { - cooked: string; - raw: string; - }; -} - -export interface AssignmentProperty extends Property { - value: Pattern; - kind: "init"; - method: boolean; // false -} - -export interface ObjectPattern extends BasePattern { - type: "ObjectPattern"; - properties: Array; -} - -export interface ArrayPattern extends BasePattern { - type: "ArrayPattern"; - elements: Array; -} - -export interface RestElement extends BasePattern { - type: "RestElement"; - argument: Pattern; -} - -export interface AssignmentPattern extends BasePattern { - type: "AssignmentPattern"; - left: Pattern; - right: Expression; -} - -export type Class = ClassDeclaration | ClassExpression; -interface BaseClass extends BaseNode { - superClass?: Expression | null; - body: ClassBody; -} - -export interface ClassBody extends BaseNode { - type: "ClassBody"; - body: Array; -} - -export interface MethodDefinition extends BaseNode { - type: "MethodDefinition"; - key: Expression; - value: FunctionExpression; - kind: "constructor" | "method" | "get" | "set"; - computed: boolean; - static: boolean; -} - -export interface ClassDeclaration extends BaseClass, BaseDeclaration { - type: "ClassDeclaration"; - /** It is null when a class declaration is a part of the `export default class` statement */ - id: Identifier | null; -} - -export interface ClassExpression extends BaseClass, BaseExpression { - type: "ClassExpression"; - id?: Identifier | null; -} - -export interface MetaProperty extends BaseExpression { - type: "MetaProperty"; - meta: Identifier; - property: Identifier; -} - -export type ModuleDeclaration = - ImportDeclaration | ExportNamedDeclaration | ExportDefaultDeclaration | - ExportAllDeclaration; -interface BaseModuleDeclaration extends BaseNode { } - -export type ModuleSpecifier = - ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | - ExportSpecifier; -interface BaseModuleSpecifier extends BaseNode { - local: Identifier; -} - -export interface ImportDeclaration extends BaseModuleDeclaration { - type: "ImportDeclaration"; - specifiers: Array; - source: Literal; -} - -export interface ImportSpecifier extends BaseModuleSpecifier { - type: "ImportSpecifier"; - imported: Identifier; -} - -export interface ImportExpression extends BaseExpression { - type: "ImportExpression"; - source: Expression; -} - -export interface ImportDefaultSpecifier extends BaseModuleSpecifier { - type: "ImportDefaultSpecifier"; -} - -export interface ImportNamespaceSpecifier extends BaseModuleSpecifier { - type: "ImportNamespaceSpecifier"; -} - -export interface ExportNamedDeclaration extends BaseModuleDeclaration { - type: "ExportNamedDeclaration"; - declaration?: Declaration | null; - specifiers: Array; - source?: Literal | null; -} - -export interface ExportSpecifier extends BaseModuleSpecifier { - type: "ExportSpecifier"; - exported: Identifier; -} - -export interface ExportDefaultDeclaration extends BaseModuleDeclaration { - type: "ExportDefaultDeclaration"; - declaration: Declaration | Expression; -} - -export interface ExportAllDeclaration extends BaseModuleDeclaration { - type: "ExportAllDeclaration"; - source: Literal; -} - -export interface AwaitExpression extends BaseExpression { - type: "AwaitExpression"; - argument: Expression; -} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/stream.d.ts b/kmath-ast/src/jsMain/kotlin/stream.d.ts deleted file mode 100644 index f98fcab8c..000000000 --- a/kmath-ast/src/jsMain/kotlin/stream.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {Emitter} from 'emitter' - -export class Stream extends Emitter { - pipe(dest: any, options: any): any -} From 4294bc1b97edbad2f7a6cfe3ea57409aa03bf611 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 19:23:10 +0700 Subject: [PATCH 16/39] Hide bindings from public API --- kmath-ast/src/jsMain/kotlin/astring.global.kt | 17 -- .../src/jsMain/kotlin/astring.typealises.kt | 3 - .../src/jsMain/kotlin/estree.extensions.kt | 67 ------- .../kmath/estree/internal/JSBuilder.kt | 17 +- .../kmath/estree/internal/astring}/astring.kt | 17 +- .../internal/astring/astring.typealises.kt | 3 + .../kmath/estree/internal/emitter}/emitter.kt | 14 +- .../internal/estree/estree.extensions.kt | 74 +++++++ .../kmath/estree/internal/estree}/estree.kt | 183 +++++++++--------- .../kmath/estree/internal/stream/stream.kt | 7 + .../internal/tsstdlib/lib.es2015.iterable.kt | 25 +++ .../estree/internal/tsstdlib}/lib.es5.kt | 22 +-- .../src/jsMain/kotlin/lib.es2015.iterable.kt | 28 --- kmath-ast/src/jsMain/kotlin/stream.kt | 13 -- 14 files changed, 230 insertions(+), 260 deletions(-) delete mode 100644 kmath-ast/src/jsMain/kotlin/astring.global.kt delete mode 100644 kmath-ast/src/jsMain/kotlin/astring.typealises.kt delete mode 100644 kmath-ast/src/jsMain/kotlin/estree.extensions.kt rename kmath-ast/src/jsMain/kotlin/{ => kscience/kmath/estree/internal/astring}/astring.kt (57%) create mode 100644 kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.typealises.kt rename kmath-ast/src/jsMain/kotlin/{ => kscience/kmath/estree/internal/emitter}/emitter.kt (51%) create mode 100644 kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt rename kmath-ast/src/jsMain/kotlin/{ => kscience/kmath/estree/internal/estree}/estree.kt (88%) create mode 100644 kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/stream/stream.kt create mode 100644 kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt rename kmath-ast/src/jsMain/kotlin/{ => kscience/kmath/estree/internal/tsstdlib}/lib.es5.kt (77%) delete mode 100644 kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt delete mode 100644 kmath-ast/src/jsMain/kotlin/stream.kt diff --git a/kmath-ast/src/jsMain/kotlin/astring.global.kt b/kmath-ast/src/jsMain/kotlin/astring.global.kt deleted file mode 100644 index d8514c310..000000000 --- a/kmath-ast/src/jsMain/kotlin/astring.global.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:JsQualifier("global") -@file:Suppress( - "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "PackageDirectoryMismatch", "ClassName" -) - -package global - -import Generator - -@Suppress("EXTERNAL_DELEGATION", "NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface astring { - var generate: (dynamic, dynamic) -> dynamic - var baseGenerator: Generator - - companion object : astring by definedExternally -} diff --git a/kmath-ast/src/jsMain/kotlin/astring.typealises.kt b/kmath-ast/src/jsMain/kotlin/astring.typealises.kt deleted file mode 100644 index 9b74e2d04..000000000 --- a/kmath-ast/src/jsMain/kotlin/astring.typealises.kt +++ /dev/null @@ -1,3 +0,0 @@ -@file:Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation") - -typealias Generator = Any diff --git a/kmath-ast/src/jsMain/kotlin/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/estree.extensions.kt deleted file mode 100644 index d4fc4baa1..000000000 --- a/kmath-ast/src/jsMain/kotlin/estree.extensions.kt +++ /dev/null @@ -1,67 +0,0 @@ -@file:Suppress( - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", - "NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING", "PackageDirectoryMismatch" -) - -package estree - -fun Program(sourceType: String, vararg body: dynamic) = object : Program { - override var type = "Program" - override var sourceType = sourceType - override var body = body -} - -fun VariableDeclaration(kind: String, vararg declarations: VariableDeclarator) = object : VariableDeclaration { - override var type = "VariableDeclaration" - override var declarations = declarations.toList().toTypedArray() - override var kind = kind -} - -fun VariableDeclarator(id: dynamic, init: dynamic) = object : VariableDeclarator { - override var type = "VariableDeclarator" - override var id = id - override var init = init -} - -fun Identifier(name: String) = object : Identifier { - override var type = "Identifier" - override var name = name -} - -fun FunctionExpression(params: Array, body: BlockStatement) = object : FunctionExpression { - override var params = params - override var type = "FunctionExpression" - override var body = body -} - -fun BlockStatement(vararg body: dynamic) = object : BlockStatement { - override var type = "BlockStatement" - override var body = body -} - -fun ReturnStatement(argument: dynamic) = object : ReturnStatement { - override var type = "ReturnStatement" - override var argument = argument -} - -fun SimpleLiteral(value: dynamic) = object : SimpleLiteral { - override var type = "Literal" - override var value = value -} - -fun MemberExpression(computed: Boolean, optional: Boolean, `object`: dynamic, property: dynamic) = - object : MemberExpression { - override var type = "MemberExpression" - override var computed = computed - override var optional = optional - override var `object` = `object` - override var property = property - } - -fun SimpleCallExpression(optional: Boolean, callee: dynamic, vararg arguments: dynamic) = - object : SimpleCallExpression { - override var type = "CallExpression" - override var optional = optional - override var callee = callee - override var arguments = arguments - } diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt index c6a36b538..b38be085d 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -1,18 +1,29 @@ package kscience.kmath.estree.internal -import astring.generate +import kscience.kmath.estree.internal.astring.generate import estree.* +import kscience.kmath.estree.internal.estree.* +import kscience.kmath.estree.internal.estree.BlockStatement +import kscience.kmath.estree.internal.estree.FunctionExpression +import kscience.kmath.estree.internal.estree.Identifier +import kscience.kmath.estree.internal.estree.MemberExpression +import kscience.kmath.estree.internal.estree.Program +import kscience.kmath.estree.internal.estree.ReturnStatement +import kscience.kmath.estree.internal.estree.SimpleCallExpression +import kscience.kmath.estree.internal.estree.SimpleLiteral +import kscience.kmath.estree.internal.estree.VariableDeclaration +import kscience.kmath.estree.internal.estree.VariableDeclarator import kscience.kmath.expressions.Expression import kscience.kmath.expressions.Symbol internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) { private class GeneratedExpression(val executable: dynamic, val constants: Array) : Expression { @Suppress("UNUSED_VARIABLE", "PARAMETER_NAME_CHANGED_ON_OVERRIDE") - override fun invoke(map: Map): T { + override fun invoke(arguments: Map): T { val e = executable val c = constants val a = js("{}") - map.forEach { (key, value) -> a[key.identity] = value } + arguments.forEach { (key, value) -> a[key.identity] = value } return js("e(c, a)").unsafeCast() } } diff --git a/kmath-ast/src/jsMain/kotlin/astring.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt similarity index 57% rename from kmath-ast/src/jsMain/kotlin/astring.kt rename to kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt index fe2b2da0a..4ef3acf20 100644 --- a/kmath-ast/src/jsMain/kotlin/astring.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt @@ -1,16 +1,11 @@ -@file:Suppress( - "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "PackageDirectoryMismatch" -) - @file:JsModule("astring") @file:JsNonModule -package astring -import Generator +package kscience.kmath.estree.internal.astring + import estree.BaseNode -external interface Options { +internal external interface Options { var indent: String? get() = definedExternally set(value) = definedExternally @@ -31,8 +26,8 @@ external interface Options { set(value) = definedExternally } -external fun generate(node: BaseNode, options: Options /* Options & `T$0` */ = definedExternally): String +internal external fun generate(node: BaseNode, options: Options /* Options & `T$0` */ = definedExternally): String -external fun generate(node: BaseNode): String +internal external fun generate(node: BaseNode): String -external var baseGenerator: Generator +internal external var baseGenerator: Generator diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.typealises.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.typealises.kt new file mode 100644 index 000000000..5a7fe4f16 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.typealises.kt @@ -0,0 +1,3 @@ +package kscience.kmath.estree.internal.astring + +internal typealias Generator = Any diff --git a/kmath-ast/src/jsMain/kotlin/emitter.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/emitter/emitter.kt similarity index 51% rename from kmath-ast/src/jsMain/kotlin/emitter.kt rename to kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/emitter/emitter.kt index 94398397f..1e0a95a16 100644 --- a/kmath-ast/src/jsMain/kotlin/emitter.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/emitter/emitter.kt @@ -1,14 +1,6 @@ -@file:Suppress( - "INTERFACE_WITH_SUPERCLASS", - "OVERRIDING_FINAL_MEMBER", - "RETURN_TYPE_MISMATCH_ON_OVERRIDE", - "CONFLICTING_OVERLOADS", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "SortModifiers", - "PackageDirectoryMismatch" -) +package kscience.kmath.estree.internal.emitter -package emitter - -external open class Emitter { +internal open external class Emitter { constructor(obj: Any) constructor() @@ -18,4 +10,4 @@ external open class Emitter { open fun emit(event: String, vararg any: Any) open fun listeners(event: String): Array<() -> Unit> open fun hasListeners(event: String): Boolean -} \ No newline at end of file +} diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt new file mode 100644 index 000000000..951cd9ef8 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt @@ -0,0 +1,74 @@ +package kscience.kmath.estree.internal.estree + +import estree.* +import estree.BlockStatement +import estree.FunctionExpression +import estree.Identifier +import estree.MemberExpression +import estree.Program +import estree.ReturnStatement +import estree.SimpleCallExpression +import estree.SimpleLiteral +import estree.VariableDeclaration +import estree.VariableDeclarator + +internal fun Program(sourceType: String, vararg body: dynamic) = object : Program { + override var type = "Program" + override var sourceType = sourceType + override var body = body +} + +internal fun VariableDeclaration(kind: String, vararg declarations: VariableDeclarator) = object : VariableDeclaration { + override var type = "VariableDeclaration" + override var declarations = declarations.toList().toTypedArray() + override var kind = kind +} + +internal fun VariableDeclarator(id: dynamic, init: dynamic) = object : VariableDeclarator { + override var type = "VariableDeclarator" + override var id = id + override var init = init +} + +internal fun Identifier(name: String) = object : Identifier { + override var type = "Identifier" + override var name = name +} + +internal fun FunctionExpression(params: Array, body: BlockStatement) = object : FunctionExpression { + override var params = params + override var type = "FunctionExpression" + override var body = body +} + +internal fun BlockStatement(vararg body: dynamic) = object : BlockStatement { + override var type = "BlockStatement" + override var body = body +} + +internal fun ReturnStatement(argument: dynamic) = object : ReturnStatement { + override var type = "ReturnStatement" + override var argument = argument +} + +internal fun SimpleLiteral(value: dynamic) = object : SimpleLiteral { + override var type = "Literal" + override var value = value +} + +internal fun MemberExpression(computed: Boolean, optional: Boolean, `object`: dynamic, property: dynamic) = + object : MemberExpression { + override var type = "MemberExpression" + override var computed = computed + override var optional = optional + override var `object` = `object` + override var property = property + } + +internal fun SimpleCallExpression(optional: Boolean, callee: dynamic, vararg arguments: dynamic) = + object : SimpleCallExpression { + override var type = "CallExpression" + override var optional = optional + override var callee = callee + override var arguments = arguments + } diff --git a/kmath-ast/src/jsMain/kotlin/estree.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt similarity index 88% rename from kmath-ast/src/jsMain/kotlin/estree.kt rename to kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt index 79d043eae..8d894a1b1 100644 --- a/kmath-ast/src/jsMain/kotlin/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt @@ -1,13 +1,8 @@ -@file:Suppress( - "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "ClassName", "PackageDirectoryMismatch", -) - package estree import kotlin.js.RegExp -external interface BaseNodeWithoutComments { +internal external interface BaseNodeWithoutComments { var type: String var loc: SourceLocation? get() = definedExternally @@ -17,7 +12,7 @@ external interface BaseNodeWithoutComments { set(value) = definedExternally } -external interface BaseNode : BaseNodeWithoutComments { +internal external interface BaseNode : BaseNodeWithoutComments { var leadingComments: Array? get() = definedExternally set(value) = definedExternally @@ -26,12 +21,12 @@ external interface BaseNode : BaseNodeWithoutComments { set(value) = definedExternally } -external interface Comment : BaseNodeWithoutComments { +internal external interface Comment : BaseNodeWithoutComments { override var type: String /* "Line" | "Block" */ var value: String } -external interface SourceLocation { +internal external interface SourceLocation { var source: String? get() = definedExternally set(value) = definedExternally @@ -39,12 +34,12 @@ external interface SourceLocation { var end: Position } -external interface Position { +internal external interface Position { var line: Number var column: Number } -external interface Program : BaseNode { +internal external interface Program : BaseNode { override var type: String /* "Program" */ var sourceType: String /* "script" | "module" */ var body: Array @@ -53,7 +48,7 @@ external interface Program : BaseNode { set(value) = definedExternally } -external interface Directive : BaseNode { +internal external interface Directive : BaseNode { override var type: String /* "ExpressionStatement" */ var expression: dynamic /* SimpleLiteral | RegExpLiteral */ get() = definedExternally @@ -61,7 +56,7 @@ external interface Directive : BaseNode { var directive: String } -external interface BaseFunction : BaseNode { +internal external interface BaseFunction : BaseNode { var params: Array var generator: Boolean? get() = definedExternally @@ -74,13 +69,13 @@ external interface BaseFunction : BaseNode { set(value) = definedExternally } -external interface BaseStatement : BaseNode +internal external interface BaseStatement : BaseNode -external interface EmptyStatement : BaseStatement { +internal external interface EmptyStatement : BaseStatement { override var type: String /* "EmptyStatement" */ } -external interface BlockStatement : BaseStatement { +internal external interface BlockStatement : BaseStatement { override var type: String /* "BlockStatement" */ var body: Array var innerComments: Array? @@ -88,14 +83,14 @@ external interface BlockStatement : BaseStatement { set(value) = definedExternally } -external interface ExpressionStatement : BaseStatement { +internal external interface ExpressionStatement : BaseStatement { override var type: String /* "ExpressionStatement" */ var expression: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally set(value) = definedExternally } -external interface IfStatement : BaseStatement { +internal external interface IfStatement : BaseStatement { override var type: String /* "IfStatement" */ var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -108,7 +103,7 @@ external interface IfStatement : BaseStatement { set(value) = definedExternally } -external interface LabeledStatement : BaseStatement { +internal external interface LabeledStatement : BaseStatement { override var type: String /* "LabeledStatement" */ var label: Identifier var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ @@ -116,21 +111,21 @@ external interface LabeledStatement : BaseStatement { set(value) = definedExternally } -external interface BreakStatement : BaseStatement { +internal external interface BreakStatement : BaseStatement { override var type: String /* "BreakStatement" */ var label: Identifier? get() = definedExternally set(value) = definedExternally } -external interface ContinueStatement : BaseStatement { +internal external interface ContinueStatement : BaseStatement { override var type: String /* "ContinueStatement" */ var label: Identifier? get() = definedExternally set(value) = definedExternally } -external interface WithStatement : BaseStatement { +internal external interface WithStatement : BaseStatement { override var type: String /* "WithStatement" */ var `object`: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -140,7 +135,7 @@ external interface WithStatement : BaseStatement { set(value) = definedExternally } -external interface SwitchStatement : BaseStatement { +internal external interface SwitchStatement : BaseStatement { override var type: String /* "SwitchStatement" */ var discriminant: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -148,21 +143,21 @@ external interface SwitchStatement : BaseStatement { var cases: Array } -external interface ReturnStatement : BaseStatement { +internal external interface ReturnStatement : BaseStatement { override var type: String /* "ReturnStatement" */ var argument: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ get() = definedExternally set(value) = definedExternally } -external interface ThrowStatement : BaseStatement { +internal external interface ThrowStatement : BaseStatement { override var type: String /* "ThrowStatement" */ var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally set(value) = definedExternally } -external interface TryStatement : BaseStatement { +internal external interface TryStatement : BaseStatement { override var type: String /* "TryStatement" */ var block: BlockStatement var handler: CatchClause? @@ -173,7 +168,7 @@ external interface TryStatement : BaseStatement { set(value) = definedExternally } -external interface WhileStatement : BaseStatement { +internal external interface WhileStatement : BaseStatement { override var type: String /* "WhileStatement" */ var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -183,7 +178,7 @@ external interface WhileStatement : BaseStatement { set(value) = definedExternally } -external interface DoWhileStatement : BaseStatement { +internal external interface DoWhileStatement : BaseStatement { override var type: String /* "DoWhileStatement" */ var body: dynamic /* ExpressionStatement | BlockStatement | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | VariableDeclaration | ClassDeclaration */ get() = definedExternally @@ -193,7 +188,7 @@ external interface DoWhileStatement : BaseStatement { set(value) = definedExternally } -external interface ForStatement : BaseStatement { +internal external interface ForStatement : BaseStatement { override var type: String /* "ForStatement" */ var init: dynamic /* VariableDeclaration? | ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ get() = definedExternally @@ -209,7 +204,7 @@ external interface ForStatement : BaseStatement { set(value) = definedExternally } -external interface BaseForXStatement : BaseStatement { +internal external interface BaseForXStatement : BaseStatement { var left: dynamic /* VariableDeclaration | Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ get() = definedExternally set(value) = definedExternally @@ -221,29 +216,29 @@ external interface BaseForXStatement : BaseStatement { set(value) = definedExternally } -external interface ForInStatement : BaseForXStatement { +internal external interface ForInStatement : BaseForXStatement { override var type: String /* "ForInStatement" */ } -external interface DebuggerStatement : BaseStatement { +internal external interface DebuggerStatement : BaseStatement { override var type: String /* "DebuggerStatement" */ } -external interface BaseDeclaration : BaseStatement +internal external interface BaseDeclaration : BaseStatement -external interface FunctionDeclaration : BaseFunction, BaseDeclaration { +internal external interface FunctionDeclaration : BaseFunction, BaseDeclaration { override var type: String /* "FunctionDeclaration" */ var id: Identifier? override var body: BlockStatement } -external interface VariableDeclaration : BaseDeclaration { +internal external interface VariableDeclaration : BaseDeclaration { override var type: String /* "VariableDeclaration" */ var declarations: Array var kind: String /* "var" | "let" | "const" */ } -external interface VariableDeclarator : BaseNode { +internal external interface VariableDeclarator : BaseNode { override var type: String /* "VariableDeclarator" */ var id: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ get() = definedExternally @@ -253,30 +248,30 @@ external interface VariableDeclarator : BaseNode { set(value) = definedExternally } -external interface BaseExpression : BaseNode +internal external interface BaseExpression : BaseNode -external interface ChainExpression : BaseExpression { +internal external interface ChainExpression : BaseExpression { override var type: String /* "ChainExpression" */ var expression: dynamic /* SimpleCallExpression | MemberExpression */ get() = definedExternally set(value) = definedExternally } -external interface ThisExpression : BaseExpression { +internal external interface ThisExpression : BaseExpression { override var type: String /* "ThisExpression" */ } -external interface ArrayExpression : BaseExpression { +internal external interface ArrayExpression : BaseExpression { override var type: String /* "ArrayExpression" */ var elements: Array } -external interface ObjectExpression : BaseExpression { +internal external interface ObjectExpression : BaseExpression { override var type: String /* "ObjectExpression" */ var properties: Array } -external interface Property : BaseNode { +internal external interface Property : BaseNode { override var type: String /* "Property" */ var key: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -290,7 +285,7 @@ external interface Property : BaseNode { var computed: Boolean } -external interface FunctionExpression : BaseFunction, BaseExpression { +internal external interface FunctionExpression : BaseFunction, BaseExpression { var id: Identifier? get() = definedExternally set(value) = definedExternally @@ -298,12 +293,12 @@ external interface FunctionExpression : BaseFunction, BaseExpression { override var body: BlockStatement } -external interface SequenceExpression : BaseExpression { +internal external interface SequenceExpression : BaseExpression { override var type: String /* "SequenceExpression" */ var expressions: Array } -external interface UnaryExpression : BaseExpression { +internal external interface UnaryExpression : BaseExpression { override var type: String /* "UnaryExpression" */ var operator: String /* "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" */ var prefix: Boolean @@ -312,7 +307,7 @@ external interface UnaryExpression : BaseExpression { set(value) = definedExternally } -external interface BinaryExpression : BaseExpression { +internal external interface BinaryExpression : BaseExpression { override var type: String /* "BinaryExpression" */ var operator: String /* "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "in" | "instanceof" */ var left: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ @@ -323,7 +318,7 @@ external interface BinaryExpression : BaseExpression { set(value) = definedExternally } -external interface AssignmentExpression : BaseExpression { +internal external interface AssignmentExpression : BaseExpression { override var type: String /* "AssignmentExpression" */ var operator: String /* "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" */ var left: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ @@ -334,7 +329,7 @@ external interface AssignmentExpression : BaseExpression { set(value) = definedExternally } -external interface UpdateExpression : BaseExpression { +internal external interface UpdateExpression : BaseExpression { override var type: String /* "UpdateExpression" */ var operator: String /* "++" | "--" */ var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ @@ -343,7 +338,7 @@ external interface UpdateExpression : BaseExpression { var prefix: Boolean } -external interface LogicalExpression : BaseExpression { +internal external interface LogicalExpression : BaseExpression { override var type: String /* "LogicalExpression" */ var operator: String /* "||" | "&&" | "??" */ var left: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ @@ -354,7 +349,7 @@ external interface LogicalExpression : BaseExpression { set(value) = definedExternally } -external interface ConditionalExpression : BaseExpression { +internal external interface ConditionalExpression : BaseExpression { override var type: String /* "ConditionalExpression" */ var test: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -367,23 +362,23 @@ external interface ConditionalExpression : BaseExpression { set(value) = definedExternally } -external interface BaseCallExpression : BaseExpression { +internal external interface BaseCallExpression : BaseExpression { var callee: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression | Super */ get() = definedExternally set(value) = definedExternally var arguments: Array } -external interface SimpleCallExpression : BaseCallExpression { +internal external interface SimpleCallExpression : BaseCallExpression { override var type: String /* "CallExpression" */ var optional: Boolean } -external interface NewExpression : BaseCallExpression { +internal external interface NewExpression : BaseCallExpression { override var type: String /* "NewExpression" */ } -external interface MemberExpression : BaseExpression, BasePattern { +internal external interface MemberExpression : BaseExpression, BasePattern { override var type: String /* "MemberExpression" */ var `object`: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression | Super */ get() = definedExternally @@ -395,9 +390,9 @@ external interface MemberExpression : BaseExpression, BasePattern { var optional: Boolean } -external interface BasePattern : BaseNode +internal external interface BasePattern : BaseNode -external interface SwitchCase : BaseNode { +internal external interface SwitchCase : BaseNode { override var type: String /* "SwitchCase" */ var test: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ get() = definedExternally @@ -405,7 +400,7 @@ external interface SwitchCase : BaseNode { var consequent: Array } -external interface CatchClause : BaseNode { +internal external interface CatchClause : BaseNode { override var type: String /* "CatchClause" */ var param: dynamic /* Identifier? | ObjectPattern? | ArrayPattern? | RestElement? | AssignmentPattern? | MemberExpression? */ get() = definedExternally @@ -413,12 +408,12 @@ external interface CatchClause : BaseNode { var body: BlockStatement } -external interface Identifier : BaseNode, BaseExpression, BasePattern { +internal external interface Identifier : BaseNode, BaseExpression, BasePattern { override var type: String /* "Identifier" */ var name: String } -external interface SimpleLiteral : BaseNode, BaseExpression { +internal external interface SimpleLiteral : BaseNode, BaseExpression { override var type: String /* "Literal" */ var value: dynamic /* String? | Boolean? | Number? */ get() = definedExternally @@ -428,12 +423,12 @@ external interface SimpleLiteral : BaseNode, BaseExpression { set(value) = definedExternally } -external interface `T$1` { +internal external interface `T$1` { var pattern: String var flags: String } -external interface RegExpLiteral : BaseNode, BaseExpression { +internal external interface RegExpLiteral : BaseNode, BaseExpression { override var type: String /* "Literal" */ var value: RegExp? get() = definedExternally @@ -444,23 +439,23 @@ external interface RegExpLiteral : BaseNode, BaseExpression { set(value) = definedExternally } -external interface ForOfStatement : BaseForXStatement { +internal external interface ForOfStatement : BaseForXStatement { override var type: String /* "ForOfStatement" */ var await: Boolean } -external interface Super : BaseNode { +internal external interface Super : BaseNode { override var type: String /* "Super" */ } -external interface SpreadElement : BaseNode { +internal external interface SpreadElement : BaseNode { override var type: String /* "SpreadElement" */ var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally set(value) = definedExternally } -external interface ArrowFunctionExpression : BaseExpression, BaseFunction { +internal external interface ArrowFunctionExpression : BaseExpression, BaseFunction { override var type: String /* "ArrowFunctionExpression" */ var expression: Boolean override var body: dynamic /* BlockStatement | ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ @@ -468,7 +463,7 @@ external interface ArrowFunctionExpression : BaseExpression, BaseFunction { set(value) = definedExternally } -external interface YieldExpression : BaseExpression { +internal external interface YieldExpression : BaseExpression { override var type: String /* "YieldExpression" */ var argument: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ get() = definedExternally @@ -476,13 +471,13 @@ external interface YieldExpression : BaseExpression { var delegate: Boolean } -external interface TemplateLiteral : BaseExpression { +internal external interface TemplateLiteral : BaseExpression { override var type: String /* "TemplateLiteral" */ var quasis: Array var expressions: Array } -external interface TaggedTemplateExpression : BaseExpression { +internal external interface TaggedTemplateExpression : BaseExpression { override var type: String /* "TaggedTemplateExpression" */ var tag: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -490,18 +485,18 @@ external interface TaggedTemplateExpression : BaseExpression { var quasi: TemplateLiteral } -external interface `T$2` { +internal external interface `T$2` { var cooked: String var raw: String } -external interface TemplateElement : BaseNode { +internal external interface TemplateElement : BaseNode { override var type: String /* "TemplateElement" */ var tail: Boolean var value: `T$2` } -external interface AssignmentProperty : Property { +internal external interface AssignmentProperty : Property { override var value: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ get() = definedExternally set(value) = definedExternally @@ -509,24 +504,24 @@ external interface AssignmentProperty : Property { override var method: Boolean } -external interface ObjectPattern : BasePattern { +internal external interface ObjectPattern : BasePattern { override var type: String /* "ObjectPattern" */ var properties: Array } -external interface ArrayPattern : BasePattern { +internal external interface ArrayPattern : BasePattern { override var type: String /* "ArrayPattern" */ var elements: Array } -external interface RestElement : BasePattern { +internal external interface RestElement : BasePattern { override var type: String /* "RestElement" */ var argument: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ get() = definedExternally set(value) = definedExternally } -external interface AssignmentPattern : BasePattern { +internal external interface AssignmentPattern : BasePattern { override var type: String /* "AssignmentPattern" */ var left: dynamic /* Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression */ get() = definedExternally @@ -536,19 +531,19 @@ external interface AssignmentPattern : BasePattern { set(value) = definedExternally } -external interface BaseClass : BaseNode { +internal external interface BaseClass : BaseNode { var superClass: dynamic /* ThisExpression? | ArrayExpression? | ObjectExpression? | FunctionExpression? | ArrowFunctionExpression? | YieldExpression? | SimpleLiteral? | RegExpLiteral? | UnaryExpression? | UpdateExpression? | BinaryExpression? | AssignmentExpression? | LogicalExpression? | MemberExpression? | ConditionalExpression? | SimpleCallExpression? | NewExpression? | SequenceExpression? | TemplateLiteral? | TaggedTemplateExpression? | ClassExpression? | MetaProperty? | Identifier? | AwaitExpression? | ImportExpression? | ChainExpression? */ get() = definedExternally set(value) = definedExternally var body: ClassBody } -external interface ClassBody : BaseNode { +internal external interface ClassBody : BaseNode { override var type: String /* "ClassBody" */ var body: Array } -external interface MethodDefinition : BaseNode { +internal external interface MethodDefinition : BaseNode { override var type: String /* "MethodDefinition" */ var key: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally @@ -559,31 +554,31 @@ external interface MethodDefinition : BaseNode { var static: Boolean } -external interface ClassDeclaration : BaseClass, BaseDeclaration { +internal external interface ClassDeclaration : BaseClass, BaseDeclaration { override var type: String /* "ClassDeclaration" */ var id: Identifier? } -external interface ClassExpression : BaseClass, BaseExpression { +internal external interface ClassExpression : BaseClass, BaseExpression { override var type: String /* "ClassExpression" */ var id: Identifier? get() = definedExternally set(value) = definedExternally } -external interface MetaProperty : BaseExpression { +internal external interface MetaProperty : BaseExpression { override var type: String /* "MetaProperty" */ var meta: Identifier var property: Identifier } -external interface BaseModuleDeclaration : BaseNode +internal external interface BaseModuleDeclaration : BaseNode -external interface BaseModuleSpecifier : BaseNode { +internal external interface BaseModuleSpecifier : BaseNode { var local: Identifier } -external interface ImportDeclaration : BaseModuleDeclaration { +internal external interface ImportDeclaration : BaseModuleDeclaration { override var type: String /* "ImportDeclaration" */ var specifiers: Array var source: dynamic /* SimpleLiteral | RegExpLiteral */ @@ -591,27 +586,27 @@ external interface ImportDeclaration : BaseModuleDeclaration { set(value) = definedExternally } -external interface ImportSpecifier : BaseModuleSpecifier { +internal external interface ImportSpecifier : BaseModuleSpecifier { override var type: String /* "ImportSpecifier" */ var imported: Identifier } -external interface ImportExpression : BaseExpression { +internal external interface ImportExpression : BaseExpression { override var type: String /* "ImportExpression" */ var source: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally set(value) = definedExternally } -external interface ImportDefaultSpecifier : BaseModuleSpecifier { +internal external interface ImportDefaultSpecifier : BaseModuleSpecifier { override var type: String /* "ImportDefaultSpecifier" */ } -external interface ImportNamespaceSpecifier : BaseModuleSpecifier { +internal external interface ImportNamespaceSpecifier : BaseModuleSpecifier { override var type: String /* "ImportNamespaceSpecifier" */ } -external interface ExportNamedDeclaration : BaseModuleDeclaration { +internal external interface ExportNamedDeclaration : BaseModuleDeclaration { override var type: String /* "ExportNamedDeclaration" */ var declaration: dynamic /* FunctionDeclaration? | VariableDeclaration? | ClassDeclaration? */ get() = definedExternally @@ -622,28 +617,28 @@ external interface ExportNamedDeclaration : BaseModuleDeclaration { set(value) = definedExternally } -external interface ExportSpecifier : BaseModuleSpecifier { +internal external interface ExportSpecifier : BaseModuleSpecifier { override var type: String /* "ExportSpecifier" */ var exported: Identifier } -external interface ExportDefaultDeclaration : BaseModuleDeclaration { +internal external interface ExportDefaultDeclaration : BaseModuleDeclaration { override var type: String /* "ExportDefaultDeclaration" */ var declaration: dynamic /* FunctionDeclaration | VariableDeclaration | ClassDeclaration | ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally set(value) = definedExternally } -external interface ExportAllDeclaration : BaseModuleDeclaration { +internal external interface ExportAllDeclaration : BaseModuleDeclaration { override var type: String /* "ExportAllDeclaration" */ var source: dynamic /* SimpleLiteral | RegExpLiteral */ get() = definedExternally set(value) = definedExternally } -external interface AwaitExpression : BaseExpression { +internal external interface AwaitExpression : BaseExpression { override var type: String /* "AwaitExpression" */ var argument: dynamic /* ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | YieldExpression | SimpleLiteral | RegExpLiteral | UnaryExpression | UpdateExpression | BinaryExpression | AssignmentExpression | LogicalExpression | MemberExpression | ConditionalExpression | SimpleCallExpression | NewExpression | SequenceExpression | TemplateLiteral | TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier | AwaitExpression | ImportExpression | ChainExpression */ get() = definedExternally set(value) = definedExternally -} \ No newline at end of file +} diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/stream/stream.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/stream/stream.kt new file mode 100644 index 000000000..b3c65a758 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/stream/stream.kt @@ -0,0 +1,7 @@ +package kscience.kmath.estree.internal.stream + +import kscience.kmath.estree.internal.emitter.Emitter + +internal open external class Stream : Emitter { + open fun pipe(dest: Any, options: Any): Any +} diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt new file mode 100644 index 000000000..22d4dd8e0 --- /dev/null +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt @@ -0,0 +1,25 @@ +package kscience.kmath.estree.internal.tsstdlib + +internal external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +internal external interface IteratorReturnResult { + var done: Boolean + var value: TReturn +} + +internal external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +internal typealias Iterator__1 = Iterator + +internal external interface Iterable + +internal external interface IterableIterator : Iterator__1 diff --git a/kmath-ast/src/jsMain/kotlin/lib.es5.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es5.kt similarity index 77% rename from kmath-ast/src/jsMain/kotlin/lib.es5.kt rename to kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es5.kt index fe3847232..70f6d9702 100644 --- a/kmath-ast/src/jsMain/kotlin/lib.es5.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/tsstdlib/lib.es5.kt @@ -1,18 +1,14 @@ -@file:Suppress( - "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "DEPRECATION", "PackageDirectoryMismatch", "KDocMissingDocumentation", - "PropertyName" -) +@file:Suppress("UNUSED_TYPEALIAS_PARAMETER", "DEPRECATION") -package tsstdlib +package kscience.kmath.estree.internal.tsstdlib import kotlin.js.RegExp -typealias RegExpMatchArray = Array +internal typealias RegExpMatchArray = Array -typealias RegExpExecArray = Array +internal typealias RegExpExecArray = Array -external interface RegExpConstructor { +internal external interface RegExpConstructor { @nativeInvoke operator fun invoke(pattern: RegExp, flags: String = definedExternally): RegExp @@ -37,7 +33,7 @@ external interface RegExpConstructor { var lastMatch: String } -external interface ConcatArray { +internal external interface ConcatArray { var length: Number @nativeGetter @@ -49,7 +45,7 @@ external interface ConcatArray { fun slice(start: Number = definedExternally, end: Number = definedExternally): Array } -external interface ArrayConstructor { +internal external interface ArrayConstructor { fun from(iterable: Iterable): Array fun from(iterable: ArrayLike): Array fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array @@ -73,7 +69,7 @@ external interface ArrayConstructor { var prototype: Array } -external interface ArrayLike { +internal external interface ArrayLike { var length: Number @nativeGetter @@ -83,4 +79,4 @@ external interface ArrayLike { operator fun set(n: Number, value: T) } -typealias Extract = Any \ No newline at end of file +internal typealias Extract = Any diff --git a/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt b/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt deleted file mode 100644 index b55785a8e..000000000 --- a/kmath-ast/src/jsMain/kotlin/lib.es2015.iterable.kt +++ /dev/null @@ -1,28 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "PackageDirectoryMismatch" -) -package tsstdlib - -external interface IteratorYieldResult { - var done: Boolean? - get() = definedExternally - set(value) = definedExternally - var value: TYield -} - -external interface IteratorReturnResult { - var done: Boolean - var value: TReturn -} - -external interface Iterator { - fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ - val `return`: ((value: TReturn) -> dynamic)? - val `throw`: ((e: Any) -> dynamic)? -} - -typealias Iterator__1 = Iterator - -external interface Iterable - -external interface IterableIterator : Iterator__1 \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/stream.kt b/kmath-ast/src/jsMain/kotlin/stream.kt deleted file mode 100644 index c6c30446c..000000000 --- a/kmath-ast/src/jsMain/kotlin/stream.kt +++ /dev/null @@ -1,13 +0,0 @@ -@file:Suppress( - "INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "SortModifiers", - "KDocMissingDocumentation", "PackageDirectoryMismatch" -) - -package stream - -import emitter.Emitter - -external open class Stream : Emitter { - open fun pipe(dest: Any, options: Any): Any -} \ No newline at end of file From d70b185b3ea80f4686e860f6edf9d8bc0c334652 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 20:41:17 +0700 Subject: [PATCH 17/39] Update documentation for Algebra, add overloads for xOperation that invokes an operation not dispatches it --- .../kscience/kmath/operations/Algebra.kt | 153 +++++++++++++++--- 1 file changed, 132 insertions(+), 21 deletions(-) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index 2661525fb..3dfd14921 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -13,21 +13,79 @@ public annotation class KMathContext */ public interface Algebra { /** - * Wraps raw string or variable. + * Wraps a raw string to [T] object. This method is designed for three purposes: + * + * 1. Mathematical constants (`e`, `pi`). + * 2. Variables for expression-like contexts (`a`, `b`, `c`...). + * 3. Literals (`{1, 2}`, (`(3; 4)`)). + * + * In case if algebra can't parse the string, this method must throw [kotlin.IllegalStateException]. + * + * @param value the raw string. + * @return an object. */ public fun symbol(value: String): T = error("Wrapping of '$value' is not supported in $this") /** - * Dynamically dispatches an unary operation with name [operation]. + * Dynamically dispatches an unary operation with the certain name. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with second `unaryOperation` overload: + * i.e. `unaryOperation(a)(b) == unaryOperation(a, b)`. + * + * @param operation the name of operation. + * @return an operation. */ public fun unaryOperation(operation: String): (arg: T) -> T = error("Unary operation $operation not defined in $this") /** - * Dynamically dispatches a binary operation with name [operation]. + * Dynamically invokes an unary operation with the certain name. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with second [unaryOperation] overload: + * i.e. `unaryOperation(a)(b) == unaryOperation(a, b)`. + * + * @param operation the name of operation. + * @param arg the argument of operation. + * @return a result of operation. + */ + public fun unaryOperation(operation: String, arg: T): T = unaryOperation(operation)(arg) + + /** + * Dynamically dispatches a binary operation with the certain name. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with second [binaryOperation] overload: + * i.e. `binaryOperation(a)(b, c) == binaryOperation(a, b, c)`. + * + * @param operation the name of operation. + * @return an operation. */ public fun binaryOperation(operation: String): (left: T, right: T) -> T = error("Binary operation $operation not defined in $this") + + /** + * Dynamically invokes a binary operation with the certain name. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with second [binaryOperation] overload: + * i.e. `binaryOperation(a)(b, c) == binaryOperation(a, b, c)`. + * + * @param operation the name of operation. + * @param left the first argument of operation. + * @param right the second argument of operation. + * @return a result of operation. + */ + public fun binaryOperation(operation: String, left: T, right: T): T = binaryOperation(operation)(left, right) } /** @@ -37,33 +95,76 @@ public interface Algebra { */ public interface NumericAlgebra : Algebra { /** - * Wraps a number. + * Wraps a number to [T] object. + * + * @param value the number to wrap. + * @return an object. */ public fun number(value: Number): T /** - * Dynamically dispatches a binary operation with name [operation] where the left argument is [Number]. + * Dynamically dispatches a binary operation with the certain name with numeric first argument. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with the other [leftSideNumberOperation] overload: + * i.e. `leftSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b)`. + * + * @param operation the name of operation. + * @return an operation. */ public fun leftSideNumberOperation(operation: String): (left: Number, right: T) -> T = { l, r -> binaryOperation(operation)(number(l), r) } -// /** -// * Dynamically calls a binary operation with name [operation] where the left argument is [Number]. -// */ -// public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = -// leftSideNumberOperation(operation)(left, right) + /** + * Dynamically invokes a binary operation with the certain name with numeric first argument. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with second [leftSideNumberOperation] overload: + * i.e. `leftSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b, c)`. + * + * @param operation the name of operation. + * @param left the first argument of operation. + * @param right the second argument of operation. + * @return a result of operation. + */ + public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = + leftSideNumberOperation(operation)(left, right) /** - * Dynamically dispatches a binary operation with name [operation] where the right argument is [Number]. + * Dynamically dispatches a binary operation with the certain name with numeric first argument. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with the other [rightSideNumberOperation] overload: + * i.e. `rightSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b, c)`. + * + * @param operation the name of operation. + * @return an operation. */ public fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = { l, r -> binaryOperation(operation)(l, number(r)) } -// /** -// * Dynamically calls a binary operation with name [operation] where the right argument is [Number]. -// */ -// public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = -// rightSideNumberOperation(operation)(left, right) + /** + * Dynamically invokes a binary operation with the certain name with numeric second argument. + * + * This function must follow two properties: + * + * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. + * 2. This function is symmetric with the other [rightSideNumberOperation] overload: + * i.e. `rightSideNumberOperation(a)(b, c) == rightSideNumberOperation(a, b, c)`. + * + * @param operation the name of operation. + * @param left the first argument of operation. + * @param right the second argument of operation. + * @return a result of operation. + */ + public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = + rightSideNumberOperation(operation)(left, right) } /** @@ -160,13 +261,13 @@ public interface SpaceOperations : Algebra { */ public operator fun Number.times(b: T): T = b * this - override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { + public override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { PLUS_OPERATION -> { arg -> arg } MINUS_OPERATION -> { arg -> -arg } else -> super.unaryOperation(operation) } - override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { PLUS_OPERATION -> ::add MINUS_OPERATION -> { left, right -> left - right } else -> super.binaryOperation(operation) @@ -196,6 +297,11 @@ public interface Space : SpaceOperations { * The neutral element of addition. */ public val zero: T + + public override fun symbol(value: String): T = when (value) { + "zero" -> zero + else -> super.symbol(value) + } } /** @@ -221,7 +327,7 @@ public interface RingOperations : SpaceOperations { */ public operator fun T.times(b: T): T = multiply(this, b) - override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { TIMES_OPERATION -> ::multiply else -> super.binaryOperation(operation) } @@ -246,7 +352,12 @@ public interface Ring : Space, RingOperations, NumericAlgebra { */ public val one: T - override fun number(value: Number): T = one * value.toDouble() + public override fun number(value: Number): T = one * value.toDouble() + + public override fun symbol(value: String): T = when (value) { + "one" -> one + else -> super.symbol(value) + } /** * Addition of element and scalar. @@ -308,7 +419,7 @@ public interface FieldOperations : RingOperations { */ public operator fun T.div(b: T): T = divide(this, b) - override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { DIV_OPERATION -> ::divide else -> super.binaryOperation(operation) } From 9fbca45235ba88186170a2f909c456abac5ef71e Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 20:48:38 +0700 Subject: [PATCH 18/39] Fix incorrect properties in verifier classes --- .../kotlin/kscience/kmath/operations/internal/FieldVerifier.kt | 2 ++ .../kotlin/kscience/kmath/operations/internal/RingVerifier.kt | 2 +- .../kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt index 1ca09ab0c..89f31c75b 100644 --- a/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt +++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt @@ -12,6 +12,8 @@ internal class FieldVerifier(override val algebra: Field, a: T, b: T, c: T super.verify() algebra { + assertEquals(a + b, b + a, "Addition in $algebra is not commutative.") + assertEquals(a * b, b * a, "Multiplication in $algebra is not commutative.") assertNotEquals(a / b, b / a, "Division in $algebra is not anti-commutative.") assertNotEquals((a / b) / c, a / (b / c), "Division in $algebra is associative.") assertEquals((a + b) / c, (a / c) + (b / c), "Division in $algebra is not right-distributive.") diff --git a/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt index 863169b9b..359ba1701 100644 --- a/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt +++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt @@ -10,7 +10,7 @@ internal open class RingVerifier(override val algebra: Ring, a: T, b: T, c super.verify() algebra { - assertEquals(a * b, a * b, "Multiplication in $algebra is not commutative.") + assertEquals(a + b, b + a, "Addition in $algebra is not commutative.") assertEquals(a * b * c, a * (b * c), "Multiplication in $algebra is not associative.") assertEquals(c * (a + b), (c * a) + (c * b), "Multiplication in $algebra is not distributive.") assertEquals(a * one, one * a, "$one in $algebra is not a neutral multiplication element.") diff --git a/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt index 4dc855829..045abb71f 100644 --- a/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt +++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt @@ -15,7 +15,6 @@ internal open class SpaceVerifier( AlgebraicVerifier> { override fun verify() { algebra { - assertEquals(a + b, b + a, "Addition in $algebra is not commutative.") assertEquals(a + b + c, a + (b + c), "Addition in $algebra is not associative.") assertEquals(x * (a + b), x * a + x * b, "Addition in $algebra is not distributive.") assertEquals((a + b) * x, a * x + b * x, "Addition in $algebra is not distributive.") From c8df741a4e2c7d45f25d4ce8c083250a524f514a Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 20:58:52 +0700 Subject: [PATCH 19/39] Remove incorrent symbol decl. --- .../kotlin/kscience/kmath/operations/Algebra.kt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index 3dfd14921..6cf9eeb78 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -297,11 +297,6 @@ public interface Space : SpaceOperations { * The neutral element of addition. */ public val zero: T - - public override fun symbol(value: String): T = when (value) { - "zero" -> zero - else -> super.symbol(value) - } } /** @@ -354,11 +349,6 @@ public interface Ring : Space, RingOperations, NumericAlgebra { public override fun number(value: Number): T = one * value.toDouble() - public override fun symbol(value: String): T = when (value) { - "one" -> one - else -> super.symbol(value) - } - /** * Addition of element and scalar. * From 69b1952c15150b0a4a39330ed82be52b93671d38 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 21:13:11 +0700 Subject: [PATCH 20/39] Add verification of NDField --- .../kotlin/kscience/kmath/structures/NDFieldTest.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt index 79b56ea4a..b763ec7de 100644 --- a/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt @@ -1,10 +1,16 @@ package kscience.kmath.structures +import kscience.kmath.operations.internal.FieldVerifier +import kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals +internal class NDFieldTest { + @Test + fun verify() { + (NDField.real(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } + } -class NDFieldTest { @Test fun testStrides() { val ndArray = NDElement.real(intArrayOf(10, 10)) { (it[0] + it[1]).toDouble() } From 12d64220659051a9723446c4f0b86559b1a1d199 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 21:43:04 +0700 Subject: [PATCH 21/39] Fix wrong package --- .../jsMain/kotlin/kscience/kmath/estree/Codegen.kt | 1 + .../kscience/kmath/estree/internal/JSBuilder.kt | 11 ----------- .../kmath/estree/internal/astring/astring.kt | 2 +- .../estree/internal/estree/estree.extensions.kt | 12 ------------ .../kscience/kmath/estree/internal/estree/estree.kt | 2 +- 5 files changed, 3 insertions(+), 25 deletions(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt index d10c9c0cf..50454fa34 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt @@ -4,6 +4,7 @@ import estree.* import kscience.kmath.ast.MST import kscience.kmath.ast.MstExpression import kscience.kmath.estree.internal.JSBuilder +import kscience.kmath.estree.internal.estree.BaseExpression import kscience.kmath.expressions.Expression import kscience.kmath.operations.Algebra import kscience.kmath.operations.NumericAlgebra diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt index b38be085d..a55ac62a4 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -1,18 +1,7 @@ package kscience.kmath.estree.internal import kscience.kmath.estree.internal.astring.generate -import estree.* import kscience.kmath.estree.internal.estree.* -import kscience.kmath.estree.internal.estree.BlockStatement -import kscience.kmath.estree.internal.estree.FunctionExpression -import kscience.kmath.estree.internal.estree.Identifier -import kscience.kmath.estree.internal.estree.MemberExpression -import kscience.kmath.estree.internal.estree.Program -import kscience.kmath.estree.internal.estree.ReturnStatement -import kscience.kmath.estree.internal.estree.SimpleCallExpression -import kscience.kmath.estree.internal.estree.SimpleLiteral -import kscience.kmath.estree.internal.estree.VariableDeclaration -import kscience.kmath.estree.internal.estree.VariableDeclarator import kscience.kmath.expressions.Expression import kscience.kmath.expressions.Symbol diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt index 4ef3acf20..cf0a8de25 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/astring/astring.kt @@ -3,7 +3,7 @@ package kscience.kmath.estree.internal.astring -import estree.BaseNode +import kscience.kmath.estree.internal.estree.BaseNode internal external interface Options { var indent: String? diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt index 951cd9ef8..5bc197d0c 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.extensions.kt @@ -1,17 +1,5 @@ package kscience.kmath.estree.internal.estree -import estree.* -import estree.BlockStatement -import estree.FunctionExpression -import estree.Identifier -import estree.MemberExpression -import estree.Program -import estree.ReturnStatement -import estree.SimpleCallExpression -import estree.SimpleLiteral -import estree.VariableDeclaration -import estree.VariableDeclarator - internal fun Program(sourceType: String, vararg body: dynamic) = object : Program { override var type = "Program" override var sourceType = sourceType diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt index 8d894a1b1..a5385d1ee 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/estree/estree.kt @@ -1,4 +1,4 @@ -package estree +package kscience.kmath.estree.internal.estree import kotlin.js.RegExp From 7002bdb5bdd37fce26c0b63195a3b6db462082c7 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 21:45:02 +0700 Subject: [PATCH 22/39] Remove redundant suppression --- .../jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt index a55ac62a4..6845437b3 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt @@ -7,7 +7,7 @@ import kscience.kmath.expressions.Symbol internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) { private class GeneratedExpression(val executable: dynamic, val constants: Array) : Expression { - @Suppress("UNUSED_VARIABLE", "PARAMETER_NAME_CHANGED_ON_OVERRIDE") + @Suppress("UNUSED_VARIABLE") override fun invoke(arguments: Map): T { val e = executable val c = constants From 306eaecdb1cd323525ff0be855e55ada4a4a6160 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 21:55:20 +0700 Subject: [PATCH 23/39] Remove invalid import --- kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt index 50454fa34..f5727fb16 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt @@ -1,6 +1,5 @@ package kscience.kmath.estree -import estree.* import kscience.kmath.ast.MST import kscience.kmath.ast.MstExpression import kscience.kmath.estree.internal.JSBuilder From cfc13cda8fbc97137ee9345942531611b3aa5367 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 12:57:50 +0700 Subject: [PATCH 24/39] Rename files and JSBuilder --- .../kotlin/kscience/kmath/estree/{Codegen.kt => estree.kt} | 6 +++--- .../estree/internal/{JSBuilder.kt => ESTreeBuilder.kt} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/{Codegen.kt => estree.kt} (92%) rename kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/{JSBuilder.kt => ESTreeBuilder.kt} (96%) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt similarity index 92% rename from kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt rename to kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt index f5727fb16..5036e96c0 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/Codegen.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt @@ -2,7 +2,7 @@ package kscience.kmath.estree import kscience.kmath.ast.MST import kscience.kmath.ast.MstExpression -import kscience.kmath.estree.internal.JSBuilder +import kscience.kmath.estree.internal.ESTreeBuilder import kscience.kmath.estree.internal.estree.BaseExpression import kscience.kmath.expressions.Expression import kscience.kmath.operations.Algebra @@ -11,7 +11,7 @@ import kscience.kmath.operations.RealField @PublishedApi internal fun MST.compileWith(algebra: Algebra): Expression { - fun JSBuilder.visit(node: MST): BaseExpression = when (node) { + fun ESTreeBuilder.visit(node: MST): BaseExpression = when (node) { is MST.Symbolic -> { val symbol = try { algebra.symbol(node.value) @@ -57,7 +57,7 @@ internal fun MST.compileWith(algebra: Algebra): Expression { } } - return JSBuilder { visit(this@compileWith) }.instance + return ESTreeBuilder { visit(this@compileWith) }.instance } diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt similarity index 96% rename from kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt rename to kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt index 6845437b3..e58ad54b3 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/JSBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -5,7 +5,7 @@ import kscience.kmath.estree.internal.estree.* import kscience.kmath.expressions.Expression import kscience.kmath.expressions.Symbol -internal class JSBuilder(val bodyCallback: JSBuilder.() -> BaseExpression) { +internal class ESTreeBuilder(val bodyCallback: ESTreeBuilder.() -> BaseExpression) { private class GeneratedExpression(val executable: dynamic, val constants: Array) : Expression { @Suppress("UNUSED_VARIABLE") override fun invoke(arguments: Map): T { From d657f40e3f84542de429ac314a1c62a3eaad2304 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 12:58:35 +0700 Subject: [PATCH 25/39] Fix KDoc comments --- kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt index 5036e96c0..f9996b61a 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt @@ -62,7 +62,7 @@ internal fun MST.compileWith(algebra: Algebra): Expression { /** - * Compiles an [MST] to ASM using given algebra. + * Compiles an [MST] to ESTree generated expression using given algebra. * * @author Alexander Nozik. */ @@ -70,7 +70,7 @@ public fun Algebra.expression(mst: MST): Expression = mst.compileWith(this) /** - * Optimizes performance of an [MstExpression] using ASM codegen. + * Optimizes performance of an [MstExpression] by compiling it into ESTree generated expression. * * @author Alexander Nozik. */ From 46ac73d2c167be6d3cdb154b755f03c7d1f04817 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 13:11:12 +0700 Subject: [PATCH 26/39] Add undefined handling in constant insertion --- .../kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt index e58ad54b3..349686b83 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -40,9 +40,10 @@ internal class ESTreeBuilder(val bodyCallback: ESTreeBuilder.() -> BaseExp private val keys = mutableListOf() fun constant(value: Any?) = when { - value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" -> { + value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" -> SimpleLiteral(value) - } + + jsType(value) == "undefined" -> Identifier("undefined") else -> { val idx = if (value in constants) constants.indexOf(value) else constants.also { it += value }.lastIndex From 1ab6702bb4eac6a5ef1381bac29d3d3c34ac96b2 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 13:11:44 +0700 Subject: [PATCH 27/39] Delete unused property --- .../kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt index 349686b83..e03a71123 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -37,7 +37,6 @@ internal class ESTreeBuilder(val bodyCallback: ESTreeBuilder.() -> BaseExp } private val constants = mutableListOf() - private val keys = mutableListOf() fun constant(value: Any?) = when { value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" -> From d521fa0d8d7e0be670d019431209fad8ca8ab4f5 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 13:15:01 +0700 Subject: [PATCH 28/39] Fix wrong function name --- .../kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt index e03a71123..e1823813a 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -42,7 +42,7 @@ internal class ESTreeBuilder(val bodyCallback: ESTreeBuilder.() -> BaseExp value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" -> SimpleLiteral(value) - jsType(value) == "undefined" -> Identifier("undefined") + jsTypeOf(value) == "undefined" -> Identifier("undefined") else -> { val idx = if (value in constants) constants.indexOf(value) else constants.also { it += value }.lastIndex From 2310aca9dbaf151a00119bd66fc440799f8281f2 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 13:42:12 +0700 Subject: [PATCH 29/39] Improve consistency of operations in MstAlgebra --- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 20 +++++++++++++------ .../kscience/kmath/operations/Algebra.kt | 4 ++-- .../kmath/operations/NumberAlgebra.kt | 5 ++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index 96703ffb8..970ef3570 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -25,7 +25,9 @@ public object MstSpace : Space, NumericAlgebra { public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) public override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) - public override fun MST.unaryMinus(): MST = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override operator fun MST.unaryPlus(): MST = unaryOperation(SpaceOperations.PLUS_OPERATION)(this) + public override operator fun MST.unaryMinus(): MST = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override operator fun MST.minus(b: MST): MST = binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) public override fun multiply(a: MST, k: Number): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) @@ -41,17 +43,19 @@ public object MstSpace : Space, NumericAlgebra { * [Ring] over [MST] nodes. */ public object MstRing : Ring, NumericAlgebra { - override val zero: MST.Numeric + public override val zero: MST.Numeric get() = MstSpace.zero - override val one: MST.Numeric by lazy { number(1.0) } + public override val one: MST.Numeric by lazy { number(1.0) } public override fun number(value: Number): MST.Numeric = MstSpace.number(value) public override fun symbol(value: String): MST.Symbolic = MstSpace.symbol(value) public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) - public override fun MST.unaryMinus(): MST = MstSpace.unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override operator fun MST.unaryPlus(): MST = MstSpace { this@unaryPlus } + public override operator fun MST.unaryMinus(): MST = MstSpace { -this@unaryMinus } + public override operator fun MST.minus(b: MST): MST = MstSpace { this@minus - b } public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstSpace.binaryOperation(operation) @@ -76,7 +80,9 @@ public object MstField : Field { public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) - public override fun MST.unaryMinus(): MST = MstSpace.unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override operator fun MST.unaryPlus(): MST = MstRing { this@unaryPlus } + public override operator fun MST.unaryMinus(): MST = MstRing { -this@unaryMinus } + public override operator fun MST.minus(b: MST): MST = MstRing { this@minus - b } public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstRing.binaryOperation(operation) @@ -111,7 +117,9 @@ public object MstExtendedField : ExtendedField { public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) public override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b) - public override fun MST.unaryMinus(): MST = MstSpace.unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override operator fun MST.unaryPlus(): MST = MstField { this@unaryPlus } + public override operator fun MST.unaryMinus(): MST = MstField { -this@unaryMinus } + public override operator fun MST.minus(b: MST): MST = MstField { this@minus - b } public override fun power(arg: MST, pow: Number): MST.Binary = binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index 6cf9eeb78..f1ceb8858 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -275,12 +275,12 @@ public interface SpaceOperations : Algebra { public companion object { /** - * The identifier of addition. + * The identifier of addition and unary positive. */ public const val PLUS_OPERATION: String = "+" /** - * The identifier of subtraction (and negation). + * The identifier of subtraction and unary negation. */ public const val MINUS_OPERATION: String = "-" } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt index cd2bd0417..84d89b7eb 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt @@ -1,6 +1,5 @@ package kscience.kmath.operations -import kotlin.math.abs import kotlin.math.pow as kpow /** @@ -249,10 +248,10 @@ public object ByteRing : Ring, Norm { @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object LongRing : Ring, Norm { public override val zero: Long - get() = 0 + get() = 0L public override val one: Long - get() = 1 + get() = 1L public override inline fun add(a: Long, b: Long): Long = a + b public override inline fun multiply(a: Long, k: Number): Long = a * k.toLong() From c738fb1f2a5e85ee1b5ec7166d9e4aa860971627 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 13:44:52 +0700 Subject: [PATCH 30/39] Make return types more specific in MstAlgebra.kt --- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index 970ef3570..edbd7f92b 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -25,9 +25,9 @@ public object MstSpace : Space, NumericAlgebra { public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) public override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) - public override operator fun MST.unaryPlus(): MST = unaryOperation(SpaceOperations.PLUS_OPERATION)(this) - public override operator fun MST.unaryMinus(): MST = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) - public override operator fun MST.minus(b: MST): MST = binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) + public override operator fun MST.unaryPlus(): MST.Unary = unaryOperation(SpaceOperations.PLUS_OPERATION)(this) + public override operator fun MST.unaryMinus(): MST.Unary = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override operator fun MST.minus(b: MST): MST.Binary = binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) public override fun multiply(a: MST, k: Number): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) @@ -53,9 +53,9 @@ public object MstRing : Ring, NumericAlgebra { public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) - public override operator fun MST.unaryPlus(): MST = MstSpace { this@unaryPlus } - public override operator fun MST.unaryMinus(): MST = MstSpace { -this@unaryMinus } - public override operator fun MST.minus(b: MST): MST = MstSpace { this@minus - b } + public override operator fun MST.unaryPlus(): MST.Unary = MstSpace { +this@unaryPlus } + public override operator fun MST.unaryMinus(): MST.Unary = MstSpace { -this@unaryMinus } + public override operator fun MST.minus(b: MST): MST.Binary = MstSpace { this@minus - b } public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstSpace.binaryOperation(operation) @@ -80,9 +80,9 @@ public object MstField : Field { public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) - public override operator fun MST.unaryPlus(): MST = MstRing { this@unaryPlus } - public override operator fun MST.unaryMinus(): MST = MstRing { -this@unaryMinus } - public override operator fun MST.minus(b: MST): MST = MstRing { this@minus - b } + public override operator fun MST.unaryPlus(): MST.Unary = MstRing { +this@unaryPlus } + public override operator fun MST.unaryMinus(): MST.Unary = MstRing { -this@unaryMinus } + public override operator fun MST.minus(b: MST): MST.Binary = MstRing { this@minus - b } public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = MstRing.binaryOperation(operation) @@ -100,7 +100,7 @@ public object MstExtendedField : ExtendedField { public override val one: MST.Numeric get() = MstField.one - public override fun symbol(value: String): MST = MstField.symbol(value) + public override fun symbol(value: String): MST.Symbolic = MstField.symbol(value) public override fun sin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) public override fun cos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) public override fun tan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.TAN_OPERATION)(arg) @@ -117,9 +117,9 @@ public object MstExtendedField : ExtendedField { public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) public override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b) - public override operator fun MST.unaryPlus(): MST = MstField { this@unaryPlus } - public override operator fun MST.unaryMinus(): MST = MstField { -this@unaryMinus } - public override operator fun MST.minus(b: MST): MST = MstField { this@minus - b } + public override operator fun MST.unaryPlus(): MST.Unary = MstField { +this@unaryPlus } + public override operator fun MST.unaryMinus(): MST.Unary = MstField { -this@unaryMinus } + public override operator fun MST.minus(b: MST): MST.Binary = MstField { this@minus - b } public override fun power(arg: MST, pow: Number): MST.Binary = binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) From d631c048c746fab1200ce853086b45e9ea6b0ecb Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 16:00:51 +0700 Subject: [PATCH 31/39] Fix minor problems, update README --- kmath-ast/README.md | 41 +++++++++++++++---- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 4 +- .../kscience/kmath/asm/internal/AsmBuilder.kt | 13 +++++- .../kotlin/kscience/kmath/ast/AsmTest.kt | 2 - .../kmath/ast/ParserPrecedenceTest.kt | 2 - .../kscience/kmath/operations/Algebra.kt | 4 +- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/kmath-ast/README.md b/kmath-ast/README.md index 043224800..ea89883ab 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -38,7 +38,9 @@ This subproject implements the following features: > ``` > -## Dynamic Expression Code Generation with ObjectWeb ASM +## Dynamic expression code generation + +### On JVM `kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a special implementation of `Expression` with implemented `invoke` function. @@ -55,19 +57,20 @@ RealField.mstInField { symbol("x") + 2 }.compile() package kscience.kmath.asm.generated; import java.util.Map; +import kotlin.jvm.functions.Function2; import kscience.kmath.asm.internal.MapIntrinsics; import kscience.kmath.expressions.Expression; -import kscience.kmath.operations.RealField; +import kscience.kmath.expressions.Symbol; -public final class AsmCompiledExpression_1073786867_0 implements Expression { - private final RealField algebra; +public final class AsmCompiledExpression_45045_0 implements Expression { + private final Object[] constants; - public final Double invoke(Map arguments) { - return (Double)this.algebra.add(((Double)MapIntrinsics.getOrFail(arguments, "x")).doubleValue(), 2.0D); + public final Double invoke(Map arguments) { + return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2); } - public AsmCompiledExpression_1073786867_0(RealField algebra) { - this.algebra = algebra; + public AsmCompiledExpression_45045_0(Object[] constants) { + this.constants = constants; } } @@ -82,10 +85,30 @@ RealField.mstInField { symbol("x") + 2 }.compile() RealField.expression("x+2".parseMath()) ``` -### Known issues +#### Known issues - The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class loading overhead. - This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders. Contributed by [Iaroslav Postovalov](https://github.com/CommanderTvis). + +### On JS + +A similar feature is also available on JS. + +```kotlin +RealField.mstInField { symbol("x") + 2 }.compile() +``` + +The code above returns expression implemented with such a JS function: + +```js +var executable = function (constants, arguments) { + return constants[1](constants[0](arguments, "x"), 2); +}; +``` + +#### Known issues + +- This feature uses `eval` which can be unavailable in several environments. diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index edbd7f92b..55d5b659d 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -27,7 +27,9 @@ public object MstSpace : Space, NumericAlgebra { public override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) public override operator fun MST.unaryPlus(): MST.Unary = unaryOperation(SpaceOperations.PLUS_OPERATION)(this) public override operator fun MST.unaryMinus(): MST.Unary = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) - public override operator fun MST.minus(b: MST): MST.Binary = binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) + + public override operator fun MST.minus(b: MST): MST.Binary = + binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) public override fun multiply(a: MST, k: Number): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index 882b95bf0..af7dc61b9 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -2,13 +2,16 @@ package kscience.kmath.asm.internal import kscience.kmath.asm.internal.AsmBuilder.ClassLoader import kscience.kmath.ast.MST +import kscience.kmath.ast.mstInField import kscience.kmath.expressions.Expression +import kscience.kmath.operations.RealField import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* import org.objectweb.asm.Type.* import org.objectweb.asm.commons.InstructionAdapter import java.lang.invoke.MethodHandles import java.lang.invoke.MethodType +import java.lang.reflect.Modifier import java.util.stream.Collectors.toMap import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -82,7 +85,7 @@ internal class AsmBuilder( ACC_PUBLIC or ACC_FINAL, "invoke", getMethodDescriptor(tType, MAP_TYPE), - "(L${MAP_TYPE.internalName}<${STRING_TYPE.descriptor}+${tType.descriptor}>;)${tType.descriptor}", + "(L${MAP_TYPE.internalName}<${SYMBOL_TYPE.descriptor}${if (Modifier.isFinal(classOfT.modifiers)) "" else "+"}${tType.descriptor}>;)${tType.descriptor}", null, ).instructionAdapter { invokeMethodVisitor = this @@ -159,7 +162,7 @@ internal class AsmBuilder( "", getMethodDescriptor(VOID_TYPE, *OBJECT_ARRAY_TYPE.wrapToArrayIf { hasConstants }), null, - null + null, ).instructionAdapter { val l0 = label() load(0, classType) @@ -190,6 +193,7 @@ internal class AsmBuilder( } val cls = classLoader.defineClass(className, classWriter.toByteArray()) + java.io.File("dump.class").writeBytes(classWriter.toByteArray()) val l = MethodHandles.publicLookup() if (hasConstants) @@ -334,5 +338,10 @@ internal class AsmBuilder( * ASM type for MapIntrinsics. */ val MAP_INTRINSICS_TYPE: Type by lazy { getObjectType("kscience/kmath/asm/internal/MapIntrinsics") } + + /** + * ASM Type for [kscience.kmath.expressions.Symbol]. + */ + val SYMBOL_TYPE: Type by lazy { getObjectType("kscience/kmath/expressions/Symbol") } } } diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt index 1ca8aa5dd..992f4024e 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt @@ -2,8 +2,6 @@ package kscience.kmath.ast import kscience.kmath.asm.compile import kscience.kmath.asm.expression -import kscience.kmath.ast.mstInField -import kscience.kmath.ast.parseMath import kscience.kmath.expressions.invoke import kscience.kmath.operations.Complex import kscience.kmath.operations.ComplexField diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserPrecedenceTest.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserPrecedenceTest.kt index 1844a0991..561fe51bd 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserPrecedenceTest.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserPrecedenceTest.kt @@ -1,7 +1,5 @@ package kscience.kmath.ast -import kscience.kmath.ast.evaluate -import kscience.kmath.ast.parseMath import kscience.kmath.operations.Field import kscience.kmath.operations.RealField import kotlin.test.Test diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index f1ceb8858..d2cf8e0dd 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -275,12 +275,12 @@ public interface SpaceOperations : Algebra { public companion object { /** - * The identifier of addition and unary positive. + * The identifier of addition and unary positive operator. */ public const val PLUS_OPERATION: String = "+" /** - * The identifier of subtraction and unary negation. + * The identifier of subtraction and unary negative operator. */ public const val MINUS_OPERATION: String = "-" } From 1b0f462e54a3ab2f61a09978b63fef7bf479b7d6 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 17:49:32 +0700 Subject: [PATCH 32/39] Reformat build.gradle.kts --- kmath-ast/build.gradle.kts | 8 +++++--- .../kotlin/kscience/kmath/asm/internal/AsmBuilder.kt | 2 -- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index 1f4a87b12..574793124 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -1,3 +1,5 @@ +import ru.mipt.npm.gradle.Maturity + plugins { id("ru.mipt.npm.mpp") } @@ -38,6 +40,6 @@ kotlin.sourceSets { } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE -} \ No newline at end of file +readme { + maturity = Maturity.PROTOTYPE +} diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index af7dc61b9..1edbed28d 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -2,9 +2,7 @@ package kscience.kmath.asm.internal import kscience.kmath.asm.internal.AsmBuilder.ClassLoader import kscience.kmath.ast.MST -import kscience.kmath.ast.mstInField import kscience.kmath.expressions.Expression -import kscience.kmath.operations.RealField import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* import org.objectweb.asm.Type.* From 50b62f8a3b5a59ddabe1f17551643bac2919f66a Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 18:02:02 +0700 Subject: [PATCH 33/39] Update readme --- README.md | 13 ++++- kmath-ast/README.md | 44 ++++++++++------- kmath-ast/build.gradle.kts | 37 ++++++++++++++ kmath-ast/docs/README-TEMPLATE.md | 80 +++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 20 deletions(-) create mode 100644 kmath-ast/docs/README-TEMPLATE.md diff --git a/README.md b/README.md index 50a916d2c..0899f77cc 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,16 @@ submit a feature request if you want something to be implemented first. * ### [kmath-ast](kmath-ast) > > -> **Maturity**: EXPERIMENTAL +> **Maturity**: PROTOTYPE +> +> **Features:** +> - [expression-language](kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt) : Expression language and its parser +> - [mst](kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation +> - [mst-building](kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure +> - [mst-interpreter](kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST interpreter +> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler +> - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler +
* ### [kmath-commons](kmath-commons) @@ -122,7 +131,7 @@ submit a feature request if you want something to be implemented first. * ### [kmath-dimensions](kmath-dimensions) > > -> **Maturity**: EXPERIMENTAL +> **Maturity**: PROTOTYPE
* ### [kmath-ejml](kmath-ejml) diff --git a/kmath-ast/README.md b/kmath-ast/README.md index ea89883ab..bddc1c563 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -2,56 +2,66 @@ This subproject implements the following features: -- Expression Language and its parser. -- MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation. -- Type-safe builder for MST. -- Evaluating expressions by traversing MST. + - [expression-language](src/jvmMain/kotlin/kscience/kmath/ast/parser.kt) : Expression language and its parser + - [mst](src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation + - [mst-building](src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure + - [mst-interpreter](src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST interpreter + - [mst-jvm-codegen](src/jvmMain/kotlin/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler + - [mst-js-codegen](src/jsMain/kotlin/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler + > #### Artifact: -> This module is distributed in the artifact `kscience.kmath:kmath-ast:0.1.4-dev-8`. -> +> +> This module artifact: `kscience.kmath:kmath-ast:0.2.0-dev-4`. +> +> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-ast/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-ast/_latestVersion) +> +> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-ast/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-ast/_latestVersion) +> > **Gradle:** > > ```gradle > repositories { +> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } > maven { url 'https://dl.bintray.com/mipt-npm/kscience' } > maven { url 'https://dl.bintray.com/mipt-npm/dev' } -> maven { url https://dl.bintray.com/hotkeytlt/maven' } +> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + > } > > dependencies { -> implementation 'kscience.kmath:kmath-ast:0.1.4-dev-8' +> implementation 'kscience.kmath:kmath-ast:0.2.0-dev-4' > } > ``` > **Gradle Kotlin DSL:** > > ```kotlin > repositories { +> maven("https://dl.bintray.com/kotlin/kotlin-eap") > maven("https://dl.bintray.com/mipt-npm/kscience") > maven("https://dl.bintray.com/mipt-npm/dev") > maven("https://dl.bintray.com/hotkeytlt/maven") > } > > dependencies { -> implementation("kscience.kmath:kmath-ast:0.1.4-dev-8") +> implementation("kscience.kmath:kmath-ast:0.2.0-dev-4") > } > ``` -> ## Dynamic expression code generation ### On JVM -`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds -a special implementation of `Expression` with implemented `invoke` function. +`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds +a special implementation of `Expression` with implemented `invoke` function. -For example, the following builder: +For example, the following builder: ```kotlin RealField.mstInField { symbol("x") + 2 }.compile() ``` -… leads to generation of bytecode, which can be decompiled to the following Java class: +… leads to generation of bytecode, which can be decompiled to the following Java class: ```java package kscience.kmath.asm.generated; @@ -78,7 +88,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression { ### Example Usage -This API extends MST and MstExpression, so you may optimize as both of them: +This API extends MST and MstExpression, so you may optimize as both of them: ```kotlin RealField.mstInField { symbol("x") + 2 }.compile() @@ -88,11 +98,9 @@ RealField.expression("x+2".parseMath()) #### Known issues - The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid -class loading overhead. + class loading overhead. - This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders. -Contributed by [Iaroslav Postovalov](https://github.com/CommanderTvis). - ### On JS A similar feature is also available on JS. diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index 574793124..b2d027d35 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -42,4 +42,41 @@ kotlin.sourceSets { readme { maturity = Maturity.PROTOTYPE + propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) + + feature( + id = "expression-language", + description = "Expression language and its parser", + ref = "src/jvmMain/kotlin/kscience/kmath/ast/parser.kt" + ) + + feature( + id = "mst", + description = "MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation", + ref = "src/commonMain/kotlin/kscience/kmath/ast/MST.kt" + ) + + feature( + id = "mst-building", + description = "MST building algebraic structure", + ref = "src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt" + ) + + feature( + id = "mst-interpreter", + description = "MST interpreter", + ref = "src/commonMain/kotlin/kscience/kmath/ast/MST.kt" + ) + + feature( + id = "mst-jvm-codegen", + description = "Dynamic MST to JVM bytecode compiler", + ref = "src/jvmMain/kotlin/kscience/kmath/asm/asm.kt" + ) + + feature( + id = "mst-js-codegen", + description = "Dynamic MST to JS compiler", + ref = "src/jsMain/kotlin/kscience/kmath/estree/estree.kt" + ) } diff --git a/kmath-ast/docs/README-TEMPLATE.md b/kmath-ast/docs/README-TEMPLATE.md new file mode 100644 index 000000000..3227a2ad3 --- /dev/null +++ b/kmath-ast/docs/README-TEMPLATE.md @@ -0,0 +1,80 @@ +# Abstract Syntax Tree Expression Representation and Operations (`kmath-ast`) + +This subproject implements the following features: + +${features} + +${artifact} + +## Dynamic expression code generation + +### On JVM + +`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds +a special implementation of `Expression` with implemented `invoke` function. + +For example, the following builder: + +```kotlin +RealField.mstInField { symbol("x") + 2 }.compile() +``` + +… leads to generation of bytecode, which can be decompiled to the following Java class: + +```java +package kscience.kmath.asm.generated; + +import java.util.Map; +import kotlin.jvm.functions.Function2; +import kscience.kmath.asm.internal.MapIntrinsics; +import kscience.kmath.expressions.Expression; +import kscience.kmath.expressions.Symbol; + +public final class AsmCompiledExpression_45045_0 implements Expression { + private final Object[] constants; + + public final Double invoke(Map arguments) { + return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2); + } + + public AsmCompiledExpression_45045_0(Object[] constants) { + this.constants = constants; + } +} + +``` + +### Example Usage + +This API extends MST and MstExpression, so you may optimize as both of them: + +```kotlin +RealField.mstInField { symbol("x") + 2 }.compile() +RealField.expression("x+2".parseMath()) +``` + +#### Known issues + +- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid + class loading overhead. +- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders. + +### On JS + +A similar feature is also available on JS. + +```kotlin +RealField.mstInField { symbol("x") + 2 }.compile() +``` + +The code above returns expression implemented with such a JS function: + +```js +var executable = function (constants, arguments) { + return constants[1](constants[0](arguments, "x"), 2); +}; +``` + +#### Known issues + +- This feature uses `eval` which can be unavailable in several environments. From 1a5efd0a1730d52fa1a10540a3cf169284ff6413 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 18:17:24 +0700 Subject: [PATCH 34/39] Improve ASM and ESTree tests quality --- ...> TestESTreeConsistencyWithInterpreter.kt} | 43 ++++++++++++++----- ...ions.kt => TestESTreeOperationsSupport.kt} | 23 ++-------- .../kmath/estree/TestESTreeVariables.kt | 4 +- ...t => TestAsmConsistencyWithInterpreter.kt} | 43 ++++++++++++++----- ...essions.kt => TestAsmOperationsSupport.kt} | 2 +- .../kscience/kmath/asm/TestAsmVariables.kt | 4 +- .../kotlin/kscience/kmath/ast/AsmTest.kt | 23 ---------- 7 files changed, 73 insertions(+), 69 deletions(-) rename kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/{TestESTreeAlgebras.kt => TestESTreeConsistencyWithInterpreter.kt} (68%) rename kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/{TestESTreeExpressions.kt => TestESTreeOperationsSupport.kt} (56%) rename kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/{TestAsmAlgebras.kt => TestAsmConsistencyWithInterpreter.kt} (69%) rename kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/{TestAsmExpressions.kt => TestAsmOperationsSupport.kt} (96%) delete mode 100644 kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt similarity index 68% rename from kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt rename to kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt index 09a8ab3e5..242a4154d 100644 --- a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeAlgebras.kt +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt @@ -1,18 +1,18 @@ package kscience.kmath.estree -import kscience.kmath.ast.mstInField -import kscience.kmath.ast.mstInRing -import kscience.kmath.ast.mstInSpace +import kscience.kmath.ast.* import kscience.kmath.expressions.invoke import kscience.kmath.operations.ByteRing +import kscience.kmath.operations.ComplexField import kscience.kmath.operations.RealField +import kscience.kmath.operations.toComplex import kotlin.test.Test import kotlin.test.assertEquals -internal class TestESTreeAlgebras { +internal class TestESTreeConsistencyWithInterpreter { @Test - fun space() { - val res1 = ByteRing.mstInSpace { + fun mstSpace() { + val res1 = MstSpace.mstInSpace { binaryOperation("+")( unaryOperation("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( @@ -23,9 +23,9 @@ internal class TestESTreeAlgebras { number(1) ) + symbol("x") + zero - }("x" to 2.toByte()) + }("x" to MST.Numeric(2)) - val res2 = ByteRing.mstInSpace { + val res2 = MstSpace.mstInSpace { binaryOperation("+")( unaryOperation("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( @@ -36,13 +36,13 @@ internal class TestESTreeAlgebras { number(1) ) + symbol("x") + zero - }.compile()("x" to 2.toByte()) + }.compile()("x" to MST.Numeric(2)) assertEquals(res1, res2) } @Test - fun ring() { + fun byteRing() { val res1 = ByteRing.mstInRing { binaryOperation("+")( unaryOperation("+")( @@ -72,7 +72,7 @@ internal class TestESTreeAlgebras { } @Test - fun field() { + fun realField() { val res1 = RealField.mstInField { +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 @@ -91,4 +91,25 @@ internal class TestESTreeAlgebras { assertEquals(res1, res2) } + + @Test + fun complexField() { + val res1 = ComplexField.mstInField { + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + + number(1), + number(1) / 2 + number(2.0) * one + ) + zero + }("x" to 2.0.toComplex()) + + val res2 = ComplexField.mstInField { + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + + number(1), + number(1) / 2 + number(2.0) * one + ) + zero + }.compile()("x" to 2.0.toComplex()) + + assertEquals(res1, res2) + } } diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeOperationsSupport.kt similarity index 56% rename from kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt rename to kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeOperationsSupport.kt index 3dc259cb3..72a4669d9 100644 --- a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeExpressions.kt +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeOperationsSupport.kt @@ -3,17 +3,13 @@ package kscience.kmath.estree import kscience.kmath.ast.mstInExtendedField import kscience.kmath.ast.mstInField import kscience.kmath.ast.mstInSpace -import kscience.kmath.expressions.Expression -import kscience.kmath.expressions.StringSymbol import kscience.kmath.expressions.invoke import kscience.kmath.operations.RealField -import kotlin.math.pow import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals -import kotlin.time.measureTime -internal class TestESTreeExpressions { +internal class TestESTreeOperationsSupport { @Test fun testUnaryOperationInvocation() { val expression = RealField.mstInSpace { -symbol("x") }.compile() @@ -36,21 +32,10 @@ internal class TestESTreeExpressions { @Test fun testMultipleCalls() { - val e1 = - RealField.mstInExtendedField { sin(symbol("x")).pow(4) - 6 * symbol("x") / tanh(symbol("x")) }.compile() - - val e2 = Expression { a -> - val x = a.getValue(StringSymbol("x")) - kotlin.math.sin(x).pow(4) - 6 * x / kotlin.math.tanh(x) - } - - var r = Random(0) + val e = RealField.mstInExtendedField { sin(symbol("x")).pow(4) - 6 * symbol("x") / tanh(symbol("x")) }.compile() + val r = Random(0) var s = 0.0 - measureTime { repeat(1000000) { s += e1("x" to r.nextDouble()) } }.also(::println) - println(s) - s = 0.0 - r = Random(0) - measureTime { repeat(1000000) { s += e2("x" to r.nextDouble()) } }.also(::println) + repeat(1000000) { s += e("x" to r.nextDouble()) } println(s) } } diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt index b6f59247d..846120ee2 100644 --- a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeVariables.kt @@ -9,13 +9,13 @@ import kotlin.test.assertFailsWith internal class TestESTreeVariables { @Test - fun testVariableWithoutDefault() { + fun testVariable() { val expr = ByteRing.mstInRing { symbol("x") }.compile() assertEquals(1.toByte(), expr("x" to 1.toByte())) } @Test - fun testVariableWithoutDefaultFails() { + fun testUndefinedVariableFails() { val expr = ByteRing.mstInRing { symbol("x") }.compile() assertFailsWith { expr() } } diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt similarity index 69% rename from kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt rename to kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt index a1687c1c7..013ae789d 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmAlgebras.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt @@ -1,18 +1,18 @@ package kscience.kmath.asm -import kscience.kmath.ast.mstInField -import kscience.kmath.ast.mstInRing -import kscience.kmath.ast.mstInSpace +import kscience.kmath.ast.* import kscience.kmath.expressions.invoke import kscience.kmath.operations.ByteRing +import kscience.kmath.operations.ComplexField import kscience.kmath.operations.RealField +import kscience.kmath.operations.toComplex import kotlin.test.Test import kotlin.test.assertEquals -internal class TestAsmAlgebras { +internal class TestAsmConsistencyWithInterpreter { @Test - fun space() { - val res1 = ByteRing.mstInSpace { + fun mstSpace() { + val res1 = MstSpace.mstInSpace { binaryOperation("+")( unaryOperation("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( @@ -23,9 +23,9 @@ internal class TestAsmAlgebras { number(1) ) + symbol("x") + zero - }("x" to 2.toByte()) + }("x" to MST.Numeric(2)) - val res2 = ByteRing.mstInSpace { + val res2 = MstSpace.mstInSpace { binaryOperation("+")( unaryOperation("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( @@ -36,13 +36,13 @@ internal class TestAsmAlgebras { number(1) ) + symbol("x") + zero - }.compile()("x" to 2.toByte()) + }.compile()("x" to MST.Numeric(2)) assertEquals(res1, res2) } @Test - fun ring() { + fun byteRing() { val res1 = ByteRing.mstInRing { binaryOperation("+")( unaryOperation("+")( @@ -72,7 +72,7 @@ internal class TestAsmAlgebras { } @Test - fun field() { + fun realField() { val res1 = RealField.mstInField { +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 @@ -91,4 +91,25 @@ internal class TestAsmAlgebras { assertEquals(res1, res2) } + + @Test + fun complexField() { + val res1 = ComplexField.mstInField { + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + + number(1), + number(1) / 2 + number(2.0) * one + ) + zero + }("x" to 2.0.toComplex()) + + val res2 = ComplexField.mstInField { + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + + number(1), + number(1) / 2 + number(2.0) * one + ) + zero + }.compile()("x" to 2.0.toComplex()) + + assertEquals(res1, res2) + } } diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmOperationsSupport.kt similarity index 96% rename from kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt rename to kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmOperationsSupport.kt index acd9e21ea..2ce52aa87 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmExpressions.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmOperationsSupport.kt @@ -9,7 +9,7 @@ import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals -internal class TestAsmExpressions { +internal class TestAsmOperationsSupport { @Test fun testUnaryOperationInvocation() { val expression = RealField.mstInSpace { -symbol("x") }.compile() diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt index 0ebc31be4..c91568dbf 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmVariables.kt @@ -9,13 +9,13 @@ import kotlin.test.assertFailsWith internal class TestAsmVariables { @Test - fun testVariableWithoutDefault() { + fun testVariable() { val expr = ByteRing.mstInRing { symbol("x") }.compile() assertEquals(1.toByte(), expr("x" to 1.toByte())) } @Test - fun testVariableWithoutDefaultFails() { + fun testUndefinedVariableFails() { val expr = ByteRing.mstInRing { symbol("x") }.compile() assertFailsWith { expr() } } diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt deleted file mode 100644 index 992f4024e..000000000 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/AsmTest.kt +++ /dev/null @@ -1,23 +0,0 @@ -package kscience.kmath.ast - -import kscience.kmath.asm.compile -import kscience.kmath.asm.expression -import kscience.kmath.expressions.invoke -import kscience.kmath.operations.Complex -import kscience.kmath.operations.ComplexField -import kotlin.test.Test -import kotlin.test.assertEquals - -internal class AsmTest { - @Test - fun `compile MST`() { - val res = ComplexField.expression("2+2*(2+2)".parseMath())() - assertEquals(Complex(10.0, 0.0), res) - } - - @Test - fun `compile MSTExpression`() { - val res = ComplexField.mstInField { number(2) + number(2) * (number(2) + number(2)) }.compile()() - assertEquals(Complex(10.0, 0.0), res) - } -} From 024800605f852eac9f3934961243c288adfa31aa Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 22 Dec 2020 22:20:30 +0700 Subject: [PATCH 35/39] Update ASM --- kmath-ast/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index b2d027d35..39de4256d 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -34,8 +34,8 @@ kotlin.sourceSets { jvmMain { dependencies { api("com.github.h0tk3y.betterParse:better-parse:0.4.0") - implementation("org.ow2.asm:asm:8.0.1") - implementation("org.ow2.asm:asm-commons:8.0.1") + implementation("org.ow2.asm:asm:9.0") + implementation("org.ow2.asm:asm-commons:9.0") } } } From 2c7cb1b04fc06ac68176aa05d5d2504754f94e53 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 5 Jan 2021 19:56:42 +0700 Subject: [PATCH 36/39] Rename ...Operation functions returning function to ...OperationFunction --- .../kotlin/kscience/kmath/ast/MST.kt | 12 +-- .../kotlin/kscience/kmath/ast/MstAlgebra.kt | 76 +++++++++---------- .../kscience/kmath/ast/MstExpression.kt | 4 +- .../kotlin/kscience/kmath/estree/estree.kt | 10 +-- .../TestESTreeConsistencyWithInterpreter.kt | 24 +++--- .../kmath/estree/TestESTreeSpecialization.kt | 14 ++-- .../jvmMain/kotlin/kscience/kmath/asm/asm.kt | 10 +-- .../asm/TestAsmConsistencyWithInterpreter.kt | 24 +++--- .../kmath/asm/TestAsmSpecialization.kt | 14 ++-- .../kotlin/kscience/kmath/ast/ParserTest.kt | 4 +- .../FunctionalExpressionAlgebra.kt | 62 +++++++-------- .../kscience/kmath/linear/MatrixContext.kt | 4 +- .../kscience/kmath/operations/Algebra.kt | 62 +++++++-------- .../kmath/operations/NumberAlgebra.kt | 16 ++-- 14 files changed, 168 insertions(+), 168 deletions(-) diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt index 4ff4d7354..6cf746722 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt @@ -57,22 +57,22 @@ public fun Algebra.evaluate(node: MST): T = when (node) { ?: error("Numeric nodes are not supported by $this") is MST.Symbolic -> symbol(node.value) - is MST.Unary -> unaryOperation(node.operation)(evaluate(node.value)) + is MST.Unary -> unaryOperationFunction(node.operation)(evaluate(node.value)) is MST.Binary -> when { - this !is NumericAlgebra -> binaryOperation(node.operation)(evaluate(node.left), evaluate(node.right)) + this !is NumericAlgebra -> binaryOperationFunction(node.operation)(evaluate(node.left), evaluate(node.right)) node.left is MST.Numeric && node.right is MST.Numeric -> { val number = RealField - .binaryOperation(node.operation) + .binaryOperationFunction(node.operation) .invoke(node.left.value.toDouble(), node.right.value.toDouble()) number(number) } - node.left is MST.Numeric -> leftSideNumberOperation(node.operation)(node.left.value, evaluate(node.right)) - node.right is MST.Numeric -> rightSideNumberOperation(node.operation)(evaluate(node.left), node.right.value) - else -> binaryOperation(node.operation)(evaluate(node.left), evaluate(node.right)) + node.left is MST.Numeric -> leftSideNumberOperationFunction(node.operation)(node.left.value, evaluate(node.right)) + node.right is MST.Numeric -> rightSideNumberOperationFunction(node.operation)(evaluate(node.left), node.right.value) + else -> binaryOperationFunction(node.operation)(evaluate(node.left), evaluate(node.right)) } } diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt index 55d5b659d..80b164a7c 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt @@ -9,10 +9,10 @@ public object MstAlgebra : NumericAlgebra { public override fun number(value: Number): MST.Numeric = MST.Numeric(value) public override fun symbol(value: String): MST.Symbolic = MST.Symbolic(value) - public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = + public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = { arg -> MST.Unary(operation, arg) } - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = + public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary = { left, right -> MST.Binary(operation, left, right) } } @@ -24,21 +24,21 @@ public object MstSpace : Space, NumericAlgebra { public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) - public override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) - public override operator fun MST.unaryPlus(): MST.Unary = unaryOperation(SpaceOperations.PLUS_OPERATION)(this) - public override operator fun MST.unaryMinus(): MST.Unary = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) + public override fun add(a: MST, b: MST): MST.Binary = binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b) + public override operator fun MST.unaryPlus(): MST.Unary = unaryOperationFunction(SpaceOperations.PLUS_OPERATION)(this) + public override operator fun MST.unaryMinus(): MST.Unary = unaryOperationFunction(SpaceOperations.MINUS_OPERATION)(this) public override operator fun MST.minus(b: MST): MST.Binary = - binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) + binaryOperationFunction(SpaceOperations.MINUS_OPERATION)(this, b) public override fun multiply(a: MST, k: Number): MST.Binary = - binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) + binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, number(k)) - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = - MstAlgebra.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary = + MstAlgebra.binaryOperationFunction(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = - MstAlgebra.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = + MstAlgebra.unaryOperationFunction(operation) } /** @@ -54,16 +54,16 @@ public object MstRing : Ring, NumericAlgebra { public override fun symbol(value: String): MST.Symbolic = MstSpace.symbol(value) public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) - public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) + public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b) public override operator fun MST.unaryPlus(): MST.Unary = MstSpace { +this@unaryPlus } public override operator fun MST.unaryMinus(): MST.Unary = MstSpace { -this@unaryMinus } public override operator fun MST.minus(b: MST): MST.Binary = MstSpace { this@minus - b } - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = - MstSpace.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary = + MstSpace.binaryOperationFunction(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = - MstAlgebra.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = + MstAlgebra.unaryOperationFunction(operation) } /** @@ -81,15 +81,15 @@ public object MstField : Field { public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b) public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) - public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) + public override fun divide(a: MST, b: MST): MST.Binary = binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b) public override operator fun MST.unaryPlus(): MST.Unary = MstRing { +this@unaryPlus } public override operator fun MST.unaryMinus(): MST.Unary = MstRing { -this@unaryMinus } public override operator fun MST.minus(b: MST): MST.Binary = MstRing { this@minus - b } - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = - MstRing.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary = + MstRing.binaryOperationFunction(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstRing.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = MstRing.unaryOperationFunction(operation) } /** @@ -103,18 +103,18 @@ public object MstExtendedField : ExtendedField { get() = MstField.one public override fun symbol(value: String): MST.Symbolic = MstField.symbol(value) - public override fun sin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) - public override fun cos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) - public override fun tan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.TAN_OPERATION)(arg) - public override fun asin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) - public override fun acos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) - public override fun atan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) - public override fun sinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.SINH_OPERATION)(arg) - public override fun cosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.COSH_OPERATION)(arg) - public override fun tanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.TANH_OPERATION)(arg) - public override fun asinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ASINH_OPERATION)(arg) - public override fun acosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ACOSH_OPERATION)(arg) - public override fun atanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ATANH_OPERATION)(arg) + public override fun sin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg) + public override fun cos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg) + public override fun tan(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.TAN_OPERATION)(arg) + public override fun asin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg) + public override fun acos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg) + public override fun atan(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg) + public override fun sinh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.SINH_OPERATION)(arg) + public override fun cosh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.COSH_OPERATION)(arg) + public override fun tanh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.TANH_OPERATION)(arg) + public override fun asinh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ASINH_OPERATION)(arg) + public override fun acosh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ACOSH_OPERATION)(arg) + public override fun atanh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ATANH_OPERATION)(arg) public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b) public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) @@ -124,13 +124,13 @@ public object MstExtendedField : ExtendedField { public override operator fun MST.minus(b: MST): MST.Binary = MstField { this@minus - b } public override fun power(arg: MST, pow: Number): MST.Binary = - binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) + binaryOperationFunction(PowerOperations.POW_OPERATION)(arg, number(pow)) - public override fun exp(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) - public override fun ln(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) + public override fun exp(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.EXP_OPERATION)(arg) + public override fun ln(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.LN_OPERATION)(arg) - public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = - MstField.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary = + MstField.binaryOperationFunction(operation) - public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstField.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = MstField.unaryOperationFunction(operation) } diff --git a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt index 4d1b65621..03d33aa2b 100644 --- a/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt +++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt @@ -21,8 +21,8 @@ public class MstExpression>(public val algebra: A, public null } ?: arguments.getValue(StringSymbol(value)) - override fun unaryOperation(operation: String): (arg: T) -> T = algebra.unaryOperation(operation) - override fun binaryOperation(operation: String): (left: T, right: T) -> T = algebra.binaryOperation(operation) + override fun unaryOperationFunction(operation: String): (arg: T) -> T = algebra.unaryOperationFunction(operation) + override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = algebra.binaryOperationFunction(operation) @Suppress("UNCHECKED_CAST") override fun number(value: Number): T = if (algebra is NumericAlgebra<*>) diff --git a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt index f9996b61a..159c5d5ec 100644 --- a/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt @@ -26,31 +26,31 @@ internal fun MST.compileWith(algebra: Algebra): Expression { } is MST.Numeric -> constant(node.value) - is MST.Unary -> call(algebra.unaryOperation(node.operation), visit(node.value)) + is MST.Unary -> call(algebra.unaryOperationFunction(node.operation), visit(node.value)) is MST.Binary -> when { algebra is NumericAlgebra && node.left is MST.Numeric && node.right is MST.Numeric -> constant( algebra.number( RealField - .binaryOperation(node.operation) + .binaryOperationFunction(node.operation) .invoke(node.left.value.toDouble(), node.right.value.toDouble()) ) ) algebra is NumericAlgebra && node.left is MST.Numeric -> call( - algebra.leftSideNumberOperation(node.operation), + algebra.leftSideNumberOperationFunction(node.operation), visit(node.left), visit(node.right), ) algebra is NumericAlgebra && node.right is MST.Numeric -> call( - algebra.rightSideNumberOperation(node.operation), + algebra.rightSideNumberOperationFunction(node.operation), visit(node.left), visit(node.right), ) else -> call( - algebra.binaryOperation(node.operation), + algebra.binaryOperationFunction(node.operation), visit(node.left), visit(node.right), ) diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt index 242a4154d..b9be02d49 100644 --- a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt @@ -13,8 +13,8 @@ internal class TestESTreeConsistencyWithInterpreter { @Test fun mstSpace() { val res1 = MstSpace.mstInSpace { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( add(number(1), number(1)), 2 @@ -26,8 +26,8 @@ internal class TestESTreeConsistencyWithInterpreter { }("x" to MST.Numeric(2)) val res2 = MstSpace.mstInSpace { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( add(number(1), number(1)), 2 @@ -44,8 +44,8 @@ internal class TestESTreeConsistencyWithInterpreter { @Test fun byteRing() { val res1 = ByteRing.mstInRing { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( (symbol("x") - (2.toByte() + (multiply( add(number(1), number(1)), 2 @@ -57,8 +57,8 @@ internal class TestESTreeConsistencyWithInterpreter { }("x" to 3.toByte()) val res2 = ByteRing.mstInRing { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( (symbol("x") - (2.toByte() + (multiply( add(number(1), number(1)), 2 @@ -74,7 +74,7 @@ internal class TestESTreeConsistencyWithInterpreter { @Test fun realField() { val res1 = RealField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -82,7 +82,7 @@ internal class TestESTreeConsistencyWithInterpreter { }("x" to 2.0) val res2 = RealField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -95,7 +95,7 @@ internal class TestESTreeConsistencyWithInterpreter { @Test fun complexField() { val res1 = ComplexField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -103,7 +103,7 @@ internal class TestESTreeConsistencyWithInterpreter { }("x" to 2.0.toComplex()) val res2 = ComplexField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one diff --git a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt index 0821686fc..9d0d17e58 100644 --- a/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt +++ b/kmath-ast/src/jsTest/kotlin/kscience/kmath/estree/TestESTreeSpecialization.kt @@ -9,44 +9,44 @@ import kotlin.test.assertEquals internal class TestESTreeSpecialization { @Test fun testUnaryPlus() { - val expr = RealField.mstInField { unaryOperation("+")(symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperationFunction("+")(symbol("x")) }.compile() assertEquals(2.0, expr("x" to 2.0)) } @Test fun testUnaryMinus() { - val expr = RealField.mstInField { unaryOperation("-")(symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperationFunction("-")(symbol("x")) }.compile() assertEquals(-2.0, expr("x" to 2.0)) } @Test fun testAdd() { - val expr = RealField.mstInField { binaryOperation("+")(symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperationFunction("+")(symbol("x"), symbol("x")) }.compile() assertEquals(4.0, expr("x" to 2.0)) } @Test fun testSine() { - val expr = RealField.mstInField { unaryOperation("sin")(symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperationFunction("sin")(symbol("x")) }.compile() assertEquals(0.0, expr("x" to 0.0)) } @Test fun testMinus() { - val expr = RealField.mstInField { binaryOperation("-")(symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperationFunction("-")(symbol("x"), symbol("x")) }.compile() assertEquals(0.0, expr("x" to 2.0)) } @Test fun testDivide() { - val expr = RealField.mstInField { binaryOperation("/")(symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperationFunction("/")(symbol("x"), symbol("x")) }.compile() assertEquals(1.0, expr("x" to 2.0)) } @Test fun testPower() { val expr = RealField - .mstInField { binaryOperation("pow")(symbol("x"), number(2)) } + .mstInField { binaryOperationFunction("pow")(symbol("x"), number(2)) } .compile() assertEquals(4.0, expr("x" to 2.0)) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt index 932813182..b98c0bfce 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt @@ -34,28 +34,28 @@ internal fun MST.compileWith(type: Class, algebra: Algebra): Exp } is MST.Numeric -> loadNumberConstant(node.value) - is MST.Unary -> buildCall(algebra.unaryOperation(node.operation)) { visit(node.value) } + is MST.Unary -> buildCall(algebra.unaryOperationFunction(node.operation)) { visit(node.value) } is MST.Binary -> when { algebra is NumericAlgebra && node.left is MST.Numeric && node.right is MST.Numeric -> loadObjectConstant( algebra.number( RealField - .binaryOperation(node.operation) + .binaryOperationFunction(node.operation) .invoke(node.left.value.toDouble(), node.right.value.toDouble()) ) ) - algebra is NumericAlgebra && node.left is MST.Numeric -> buildCall(algebra.leftSideNumberOperation(node.operation)) { + algebra is NumericAlgebra && node.left is MST.Numeric -> buildCall(algebra.leftSideNumberOperationFunction(node.operation)) { visit(node.left) visit(node.right) } - algebra is NumericAlgebra && node.right is MST.Numeric -> buildCall(algebra.rightSideNumberOperation(node.operation)) { + algebra is NumericAlgebra && node.right is MST.Numeric -> buildCall(algebra.rightSideNumberOperationFunction(node.operation)) { visit(node.left) visit(node.right) } - else -> buildCall(algebra.binaryOperation(node.operation)) { + else -> buildCall(algebra.binaryOperationFunction(node.operation)) { visit(node.left) visit(node.right) } diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt index 013ae789d..ae180bf3f 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt @@ -13,8 +13,8 @@ internal class TestAsmConsistencyWithInterpreter { @Test fun mstSpace() { val res1 = MstSpace.mstInSpace { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( add(number(1), number(1)), 2 @@ -26,8 +26,8 @@ internal class TestAsmConsistencyWithInterpreter { }("x" to MST.Numeric(2)) val res2 = MstSpace.mstInSpace { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( number(3.toByte()) - (number(2.toByte()) + (multiply( add(number(1), number(1)), 2 @@ -44,8 +44,8 @@ internal class TestAsmConsistencyWithInterpreter { @Test fun byteRing() { val res1 = ByteRing.mstInRing { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( (symbol("x") - (2.toByte() + (multiply( add(number(1), number(1)), 2 @@ -57,8 +57,8 @@ internal class TestAsmConsistencyWithInterpreter { }("x" to 3.toByte()) val res2 = ByteRing.mstInRing { - binaryOperation("+")( - unaryOperation("+")( + binaryOperationFunction("+")( + unaryOperationFunction("+")( (symbol("x") - (2.toByte() + (multiply( add(number(1), number(1)), 2 @@ -74,7 +74,7 @@ internal class TestAsmConsistencyWithInterpreter { @Test fun realField() { val res1 = RealField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -82,7 +82,7 @@ internal class TestAsmConsistencyWithInterpreter { }("x" to 2.0) val res2 = RealField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -95,7 +95,7 @@ internal class TestAsmConsistencyWithInterpreter { @Test fun complexField() { val res1 = ComplexField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one @@ -103,7 +103,7 @@ internal class TestAsmConsistencyWithInterpreter { }("x" to 2.0.toComplex()) val res2 = ComplexField.mstInField { - +(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( + +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")( (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 + number(1), number(1) / 2 + number(2.0) * one diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt index ce9e602d3..602c54651 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/asm/TestAsmSpecialization.kt @@ -9,44 +9,44 @@ import kotlin.test.assertEquals internal class TestAsmSpecialization { @Test fun testUnaryPlus() { - val expr = RealField.mstInField { unaryOperation("+")(symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperationFunction("+")(symbol("x")) }.compile() assertEquals(2.0, expr("x" to 2.0)) } @Test fun testUnaryMinus() { - val expr = RealField.mstInField { unaryOperation("-")(symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperationFunction("-")(symbol("x")) }.compile() assertEquals(-2.0, expr("x" to 2.0)) } @Test fun testAdd() { - val expr = RealField.mstInField { binaryOperation("+")(symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperationFunction("+")(symbol("x"), symbol("x")) }.compile() assertEquals(4.0, expr("x" to 2.0)) } @Test fun testSine() { - val expr = RealField.mstInField { unaryOperation("sin")(symbol("x")) }.compile() + val expr = RealField.mstInField { unaryOperationFunction("sin")(symbol("x")) }.compile() assertEquals(0.0, expr("x" to 0.0)) } @Test fun testMinus() { - val expr = RealField.mstInField { binaryOperation("-")(symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperationFunction("-")(symbol("x"), symbol("x")) }.compile() assertEquals(0.0, expr("x" to 2.0)) } @Test fun testDivide() { - val expr = RealField.mstInField { binaryOperation("/")(symbol("x"), symbol("x")) }.compile() + val expr = RealField.mstInField { binaryOperationFunction("/")(symbol("x"), symbol("x")) }.compile() assertEquals(1.0, expr("x" to 2.0)) } @Test fun testPower() { val expr = RealField - .mstInField { binaryOperation("pow")(symbol("x"), number(2)) } + .mstInField { binaryOperationFunction("pow")(symbol("x"), number(2)) } .compile() assertEquals(4.0, expr("x" to 2.0)) diff --git a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt index e2029ce19..3aa5392c8 100644 --- a/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt +++ b/kmath-ast/src/jvmTest/kotlin/kscience/kmath/ast/ParserTest.kt @@ -42,11 +42,11 @@ internal class ParserTest { val magicalAlgebra = object : Algebra { override fun symbol(value: String): String = value - override fun unaryOperation(operation: String): (arg: String) -> String { + override fun unaryOperationFunction(operation: String): (arg: String) -> String { throw NotImplementedError() } - override fun binaryOperation(operation: String): (left: String, right: String) -> String = + override fun binaryOperationFunction(operation: String): (left: String, right: String) -> String = when (operation) { "magic" -> { left, right -> "$left ★ $right" } else -> throw NotImplementedError() diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index e2413dea8..afbaf16e1 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -24,18 +24,18 @@ public abstract class FunctionalExpressionAlgebra>(public val /** * Builds an Expression of dynamic call of binary operation [operation] on [left] and [right]. */ - public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = + public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = { left, right -> Expression { arguments -> - algebra.binaryOperation(operation)(left.invoke(arguments), right.invoke(arguments)) + algebra.binaryOperationFunction(operation)(left.invoke(arguments), right.invoke(arguments)) } } /** * Builds an Expression of dynamic call of unary operation with name [operation] on [arg]. */ - public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = { arg -> - Expression { arguments -> algebra.unaryOperation(operation)(arg.invoke(arguments)) } + public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression = { arg -> + Expression { arguments -> algebra.unaryOperationFunction(operation)(arg.invoke(arguments)) } } } @@ -50,7 +50,7 @@ public open class FunctionalExpressionSpace>(algebra: A) : * Builds an Expression of addition of two another expressions. */ public override fun add(a: Expression, b: Expression): Expression = - binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) + binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b) /** * Builds an Expression of multiplication of expression by number. @@ -64,11 +64,11 @@ public open class FunctionalExpressionSpace>(algebra: A) : public operator fun T.plus(arg: Expression): Expression = arg + this public operator fun T.minus(arg: Expression): Expression = arg - this - public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = - super.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression = + super.unaryOperationFunction(operation) - public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = - super.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperationFunction(operation) } public open class FunctionalExpressionRing(algebra: A) : FunctionalExpressionSpace(algebra), @@ -80,16 +80,16 @@ public open class FunctionalExpressionRing(algebra: A) : FunctionalExpress * Builds an Expression of multiplication of two expressions. */ public override fun multiply(a: Expression, b: Expression): Expression = - binaryOperation(RingOperations.TIMES_OPERATION)(a, b) + binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b) public operator fun Expression.times(arg: T): Expression = this * const(arg) public operator fun T.times(arg: Expression): Expression = arg * this - public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = - super.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression = + super.unaryOperationFunction(operation) - public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = - super.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperationFunction(operation) } public open class FunctionalExpressionField(algebra: A) : @@ -99,49 +99,49 @@ public open class FunctionalExpressionField(algebra: A) : * Builds an Expression of division an expression by another one. */ public override fun divide(a: Expression, b: Expression): Expression = - binaryOperation(FieldOperations.DIV_OPERATION)(a, b) + binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b) public operator fun Expression.div(arg: T): Expression = this / const(arg) public operator fun T.div(arg: Expression): Expression = arg / this - public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = - super.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression = + super.unaryOperationFunction(operation) - public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = - super.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperationFunction(operation) } public open class FunctionalExpressionExtendedField(algebra: A) : FunctionalExpressionField(algebra), ExtendedField> where A : ExtendedField, A : NumericAlgebra { public override fun sin(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) + unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg) public override fun cos(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) + unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg) public override fun asin(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) + unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg) public override fun acos(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) + unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg) public override fun atan(arg: Expression): Expression = - unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) + unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg) public override fun power(arg: Expression, pow: Number): Expression = - binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) + binaryOperationFunction(PowerOperations.POW_OPERATION)(arg, number(pow)) public override fun exp(arg: Expression): Expression = - unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) + unaryOperationFunction(ExponentialOperations.EXP_OPERATION)(arg) - public override fun ln(arg: Expression): Expression = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) + public override fun ln(arg: Expression): Expression = unaryOperationFunction(ExponentialOperations.LN_OPERATION)(arg) - public override fun unaryOperation(operation: String): (arg: Expression) -> Expression = - super.unaryOperation(operation) + public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression = + super.unaryOperationFunction(operation) - public override fun binaryOperation(operation: String): (left: Expression, right: Expression) -> Expression = - super.binaryOperation(operation) + public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = + super.binaryOperationFunction(operation) } public inline fun > A.expressionInSpace(block: FunctionalExpressionSpace.() -> Expression): Expression = diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt index 912c3f950..648af605c 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt @@ -19,10 +19,10 @@ public interface MatrixContext> : SpaceOperations T): M @Suppress("UNCHECKED_CAST") - public override fun binaryOperation(operation: String): (left: Matrix, right: Matrix) -> M = + public override fun binaryOperationFunction(operation: String): (left: Matrix, right: Matrix) -> M = when (operation) { "dot" -> { left, right -> left dot right } - else -> super.binaryOperation(operation) as (Matrix, Matrix) -> M + else -> super.binaryOperationFunction(operation) as (Matrix, Matrix) -> M } /** diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt index d2cf8e0dd..24b417860 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt @@ -33,12 +33,12 @@ public interface Algebra { * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 2. This function is symmetric with second `unaryOperation` overload: - * i.e. `unaryOperation(a)(b) == unaryOperation(a, b)`. + * i.e. `unaryOperationFunction(a)(b) == unaryOperation(a, b)`. * * @param operation the name of operation. * @return an operation. */ - public fun unaryOperation(operation: String): (arg: T) -> T = + public fun unaryOperationFunction(operation: String): (arg: T) -> T = error("Unary operation $operation not defined in $this") /** @@ -47,14 +47,14 @@ public interface Algebra { * This function must follow two properties: * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. - * 2. This function is symmetric with second [unaryOperation] overload: - * i.e. `unaryOperation(a)(b) == unaryOperation(a, b)`. + * 2. This function is symmetric with second [unaryOperationFunction] overload: + * i.e. `unaryOperationFunction(a)(b) == unaryOperation(a, b)`. * * @param operation the name of operation. * @param arg the argument of operation. * @return a result of operation. */ - public fun unaryOperation(operation: String, arg: T): T = unaryOperation(operation)(arg) + public fun unaryOperation(operation: String, arg: T): T = unaryOperationFunction(operation)(arg) /** * Dynamically dispatches a binary operation with the certain name. @@ -62,13 +62,13 @@ public interface Algebra { * This function must follow two properties: * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. - * 2. This function is symmetric with second [binaryOperation] overload: - * i.e. `binaryOperation(a)(b, c) == binaryOperation(a, b, c)`. + * 2. This function is symmetric with second [binaryOperationFunction] overload: + * i.e. `binaryOperationFunction(a)(b, c) == binaryOperation(a, b, c)`. * * @param operation the name of operation. * @return an operation. */ - public fun binaryOperation(operation: String): (left: T, right: T) -> T = + public fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = error("Binary operation $operation not defined in $this") /** @@ -77,15 +77,15 @@ public interface Algebra { * This function must follow two properties: * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. - * 2. This function is symmetric with second [binaryOperation] overload: - * i.e. `binaryOperation(a)(b, c) == binaryOperation(a, b, c)`. + * 2. This function is symmetric with second [binaryOperationFunction] overload: + * i.e. `binaryOperationFunction(a)(b, c) == binaryOperation(a, b, c)`. * * @param operation the name of operation. * @param left the first argument of operation. * @param right the second argument of operation. * @return a result of operation. */ - public fun binaryOperation(operation: String, left: T, right: T): T = binaryOperation(operation)(left, right) + public fun binaryOperation(operation: String, left: T, right: T): T = binaryOperationFunction(operation)(left, right) } /** @@ -109,13 +109,13 @@ public interface NumericAlgebra : Algebra { * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 2. This function is symmetric with the other [leftSideNumberOperation] overload: - * i.e. `leftSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b)`. + * i.e. `leftSideNumberOperationFunction(a)(b, c) == leftSideNumberOperation(a, b)`. * * @param operation the name of operation. * @return an operation. */ - public fun leftSideNumberOperation(operation: String): (left: Number, right: T) -> T = - { l, r -> binaryOperation(operation)(number(l), r) } + public fun leftSideNumberOperationFunction(operation: String): (left: Number, right: T) -> T = + { l, r -> binaryOperationFunction(operation)(number(l), r) } /** * Dynamically invokes a binary operation with the certain name with numeric first argument. @@ -124,7 +124,7 @@ public interface NumericAlgebra : Algebra { * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 2. This function is symmetric with second [leftSideNumberOperation] overload: - * i.e. `leftSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b, c)`. + * i.e. `leftSideNumberOperationFunction(a)(b, c) == leftSideNumberOperation(a, b, c)`. * * @param operation the name of operation. * @param left the first argument of operation. @@ -132,7 +132,7 @@ public interface NumericAlgebra : Algebra { * @return a result of operation. */ public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = - leftSideNumberOperation(operation)(left, right) + leftSideNumberOperationFunction(operation)(left, right) /** * Dynamically dispatches a binary operation with the certain name with numeric first argument. @@ -140,14 +140,14 @@ public interface NumericAlgebra : Algebra { * This function must follow two properties: * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. - * 2. This function is symmetric with the other [rightSideNumberOperation] overload: - * i.e. `rightSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b, c)`. + * 2. This function is symmetric with the other [rightSideNumberOperationFunction] overload: + * i.e. `rightSideNumberOperationFunction(a)(b, c) == leftSideNumberOperation(a, b, c)`. * * @param operation the name of operation. * @return an operation. */ - public fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = - { l, r -> binaryOperation(operation)(l, number(r)) } + public fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T = + { l, r -> binaryOperationFunction(operation)(l, number(r)) } /** * Dynamically invokes a binary operation with the certain name with numeric second argument. @@ -155,8 +155,8 @@ public interface NumericAlgebra : Algebra { * This function must follow two properties: * * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. - * 2. This function is symmetric with the other [rightSideNumberOperation] overload: - * i.e. `rightSideNumberOperation(a)(b, c) == rightSideNumberOperation(a, b, c)`. + * 2. This function is symmetric with the other [rightSideNumberOperationFunction] overload: + * i.e. `rightSideNumberOperationFunction(a)(b, c) == rightSideNumberOperation(a, b, c)`. * * @param operation the name of operation. * @param left the first argument of operation. @@ -164,7 +164,7 @@ public interface NumericAlgebra : Algebra { * @return a result of operation. */ public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = - rightSideNumberOperation(operation)(left, right) + rightSideNumberOperationFunction(operation)(left, right) } /** @@ -261,16 +261,16 @@ public interface SpaceOperations : Algebra { */ public operator fun Number.times(b: T): T = b * this - public override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { + public override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) { PLUS_OPERATION -> { arg -> arg } MINUS_OPERATION -> { arg -> -arg } - else -> super.unaryOperation(operation) + else -> super.unaryOperationFunction(operation) } - public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + public override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) { PLUS_OPERATION -> ::add MINUS_OPERATION -> { left, right -> left - right } - else -> super.binaryOperation(operation) + else -> super.binaryOperationFunction(operation) } public companion object { @@ -322,9 +322,9 @@ public interface RingOperations : SpaceOperations { */ public operator fun T.times(b: T): T = multiply(this, b) - public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + public override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) { TIMES_OPERATION -> ::multiply - else -> super.binaryOperation(operation) + else -> super.binaryOperationFunction(operation) } public companion object { @@ -409,9 +409,9 @@ public interface FieldOperations : RingOperations { */ public operator fun T.div(b: T): T = divide(this, b) - public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { + public override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) { DIV_OPERATION -> ::divide - else -> super.binaryOperation(operation) + else -> super.binaryOperationFunction(operation) } public companion object { diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt index 84d89b7eb..a7b73d5e0 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt @@ -14,7 +14,7 @@ public interface ExtendedFieldOperations : public override fun tan(arg: T): T = sin(arg) / cos(arg) public override fun tanh(arg: T): T = sinh(arg) / cosh(arg) - public override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { + public override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) { TrigonometricOperations.COS_OPERATION -> ::cos TrigonometricOperations.SIN_OPERATION -> ::sin TrigonometricOperations.TAN_OPERATION -> ::tan @@ -30,7 +30,7 @@ public interface ExtendedFieldOperations : PowerOperations.SQRT_OPERATION -> ::sqrt ExponentialOperations.EXP_OPERATION -> ::exp ExponentialOperations.LN_OPERATION -> ::ln - else -> super.unaryOperation(operation) + else -> super.unaryOperationFunction(operation) } } @@ -45,10 +45,10 @@ public interface ExtendedField : ExtendedFieldOperations, Field { public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one))) public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2 - public override fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = + public override fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T = when (operation) { PowerOperations.POW_OPERATION -> ::power - else -> super.rightSideNumberOperation(operation) + else -> super.rightSideNumberOperationFunction(operation) } } @@ -80,10 +80,10 @@ public object RealField : ExtendedField, Norm { public override val one: Double get() = 1.0 - public override fun binaryOperation(operation: String): (left: Double, right: Double) -> Double = + public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double = when (operation) { PowerOperations.POW_OPERATION -> ::power - else -> super.binaryOperation(operation) + else -> super.binaryOperationFunction(operation) } public override inline fun add(a: Double, b: Double): Double = a + b @@ -131,9 +131,9 @@ public object FloatField : ExtendedField, Norm { public override val one: Float get() = 1.0f - public override fun binaryOperation(operation: String): (left: Float, right: Float) -> Float = when (operation) { + public override fun binaryOperationFunction(operation: String): (left: Float, right: Float) -> Float = when (operation) { PowerOperations.POW_OPERATION -> ::power - else -> super.binaryOperation(operation) + else -> super.binaryOperationFunction(operation) } public override inline fun add(a: Float, b: Float): Float = a + b From ea8dc63b1a327a5c773dbd33691cc48f61ee61b3 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 5 Jan 2021 20:14:50 +0700 Subject: [PATCH 37/39] Update doc comments in parser.kt --- .../src/jvmMain/kotlin/kscience/kmath/ast/parser.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt index 79cf77a6a..0b66e2c31 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt @@ -1,3 +1,5 @@ +// TODO move to common when https://github.com/h0tk3y/better-parse/pull/33 is merged + package kscience.kmath.ast import com.github.h0tk3y.betterParse.combinators.* @@ -17,7 +19,8 @@ import kscience.kmath.operations.RingOperations import kscience.kmath.operations.SpaceOperations /** - * TODO move to common after IR version is released + * better-parse implementation of grammar defined in the ArithmeticsEvaluator.g4. + * * @author Alexander Nozik and Iaroslav Postovalov */ public object ArithmeticsEvaluator : Grammar() { @@ -83,7 +86,7 @@ public object ArithmeticsEvaluator : Grammar() { } /** - * Tries to parse the string into [MST]. Returns [ParseResult] representing expression or error. + * Tries to parse the string into [MST] using [ArithmeticsEvaluator]. Returns [ParseResult] representing expression or error. * * @receiver the string to parse. * @return the [MST] node. @@ -91,7 +94,7 @@ public object ArithmeticsEvaluator : Grammar() { public fun String.tryParseMath(): ParseResult = ArithmeticsEvaluator.tryParseToEnd(this) /** - * Parses the string into [MST]. + * Parses the string into [MST] using [ArithmeticsEvaluator]. * * @receiver the string to parse. * @return the [MST] node. From fc152dec4fd514866ca37bef34a899e6bbea5e21 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 5 Jan 2021 20:15:50 +0700 Subject: [PATCH 38/39] Fix readme template --- docs/templates/ARTIFACT-TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templates/ARTIFACT-TEMPLATE.md b/docs/templates/ARTIFACT-TEMPLATE.md index c77948d4b..d46a431bd 100644 --- a/docs/templates/ARTIFACT-TEMPLATE.md +++ b/docs/templates/ARTIFACT-TEMPLATE.md @@ -14,7 +14,7 @@ > maven { url 'https://dl.bintray.com/mipt-npm/kscience' } > maven { url 'https://dl.bintray.com/mipt-npm/dev' } > maven { url 'https://dl.bintray.com/hotkeytlt/maven' } - +> > } > > dependencies { From 28ddc7cd959f4d524f3071e068f28591ab723db7 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 5 Jan 2021 20:16:42 +0700 Subject: [PATCH 39/39] Minor: regenerate readme files --- kmath-ast/README.md | 2 +- kmath-core/README.md | 2 +- kmath-for-real/README.md | 2 +- kmath-nd4j/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kmath-ast/README.md b/kmath-ast/README.md index bddc1c563..19e9ee4a9 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -26,7 +26,7 @@ This subproject implements the following features: > maven { url 'https://dl.bintray.com/mipt-npm/kscience' } > maven { url 'https://dl.bintray.com/mipt-npm/dev' } > maven { url 'https://dl.bintray.com/hotkeytlt/maven' } - +> > } > > dependencies { diff --git a/kmath-core/README.md b/kmath-core/README.md index 3a919e85a..7882e5252 100644 --- a/kmath-core/README.md +++ b/kmath-core/README.md @@ -26,7 +26,7 @@ The core features of KMath: > maven { url 'https://dl.bintray.com/mipt-npm/kscience' } > maven { url 'https://dl.bintray.com/mipt-npm/dev' } > maven { url 'https://dl.bintray.com/hotkeytlt/maven' } - +> > } > > dependencies { diff --git a/kmath-for-real/README.md b/kmath-for-real/README.md index 2ddf78e57..d6b66b7da 100644 --- a/kmath-for-real/README.md +++ b/kmath-for-real/README.md @@ -21,7 +21,7 @@ > maven { url 'https://dl.bintray.com/mipt-npm/kscience' } > maven { url 'https://dl.bintray.com/mipt-npm/dev' } > maven { url 'https://dl.bintray.com/hotkeytlt/maven' } - +> > } > > dependencies { diff --git a/kmath-nd4j/README.md b/kmath-nd4j/README.md index 176dfc09d..ff4ff4542 100644 --- a/kmath-nd4j/README.md +++ b/kmath-nd4j/README.md @@ -23,7 +23,7 @@ This subproject implements the following features: > maven { url 'https://dl.bintray.com/mipt-npm/kscience' } > maven { url 'https://dl.bintray.com/mipt-npm/dev' } > maven { url 'https://dl.bintray.com/hotkeytlt/maven' } - +> > } > > dependencies {