Dev #127
4
kmath-ast/README.md
Normal file
4
kmath-ast/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# AST based expression representation and operations
|
||||||
|
|
||||||
|
## Dynamic expression code generation
|
||||||
|
Contributed by [Iaroslav Postovalov](https://github.com/CommanderTvis).
|
@ -11,7 +11,7 @@ sealed class MST {
|
|||||||
/**
|
/**
|
||||||
* A node containing unparsed string
|
* A node containing unparsed string
|
||||||
*/
|
*/
|
||||||
data class Singular(val value: String) : MST()
|
data class Symbolic(val value: String) : MST()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node containing a number
|
* A node containing a number
|
||||||
@ -43,7 +43,7 @@ sealed class MST {
|
|||||||
fun <T> NumericAlgebra<T>.evaluate(node: MST): T {
|
fun <T> NumericAlgebra<T>.evaluate(node: MST): T {
|
||||||
return when (node) {
|
return when (node) {
|
||||||
is MST.Numeric -> number(node.value)
|
is MST.Numeric -> number(node.value)
|
||||||
is MST.Singular -> symbol(node.value)
|
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 {
|
is MST.Binary -> when {
|
||||||
node.left is MST.Numeric && node.right is MST.Numeric -> {
|
node.left is MST.Numeric && node.right is MST.Numeric -> {
|
||||||
|
47
kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt
Normal file
47
kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package scientifik.kmath.asm
|
||||||
|
|
||||||
|
import scientifik.kmath.ast.MST
|
||||||
|
import scientifik.kmath.ast.evaluate
|
||||||
|
import scientifik.kmath.expressions.Expression
|
||||||
|
import scientifik.kmath.operations.Field
|
||||||
|
import scientifik.kmath.operations.NumericAlgebra
|
||||||
|
import scientifik.kmath.operations.Ring
|
||||||
|
import scientifik.kmath.operations.Space
|
||||||
|
|
||||||
|
internal fun buildName(expression: AsmExpression<*>, collision: Int = 0): String {
|
||||||
|
val name = "scientifik.kmath.expressions.generated.AsmCompiledExpression_${expression.hashCode()}_$collision"
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName(name)
|
||||||
|
} catch (ignored: ClassNotFoundException) {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildName(expression, collision + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A : NumericAlgebra<T>, E : AsmExpressionAlgebra<T, A>> A.asm(
|
||||||
|
expressionAlgebra: E,
|
||||||
|
block: E.() -> AsmExpression<T>
|
||||||
|
): Expression<T> = expressionAlgebra.block()
|
||||||
|
|
||||||
|
inline fun <reified T : Any> NumericAlgebra<T>.asm(ast: MST): Expression<T> =
|
||||||
|
AsmExpressionAlgebra(T::class, this).evaluate(ast)
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A> A.asmSpace(block: AsmExpressionSpace<T, A>.() -> AsmExpression<T>): Expression<T> where A : NumericAlgebra<T>, A : Space<T> =
|
||||||
|
AsmExpressionSpace<T, A>(T::class, this).block()
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A> A.asmSpace(ast: MST): Expression<T> where A : NumericAlgebra<T>, A : Space<T> =
|
||||||
|
asmSpace { evaluate(ast) }
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A> A.asmRing(block: AsmExpressionRing<T, A>.() -> AsmExpression<T>): Expression<T> where A : NumericAlgebra<T>, A : Ring<T> =
|
||||||
|
AsmExpressionRing(T::class, this).block()
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A> A.asmRing(ast: MST): Expression<T> where A : NumericAlgebra<T>, A : Ring<T> =
|
||||||
|
asmRing { evaluate(ast) }
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A> A.asmField(block: AsmExpressionField<T, A>.() -> AsmExpression<T>): Expression<T> where A : NumericAlgebra<T>, A : Field<T> =
|
||||||
|
AsmExpressionField(T::class, this).block()
|
||||||
|
|
||||||
|
inline fun <reified T : Any, A> A.asmField(ast: MST): Expression<T> where A : NumericAlgebra<T>, A : Field<T> =
|
||||||
|
asmRing { evaluate(ast) }
|
@ -1,4 +1,4 @@
|
|||||||
package scietifik.kmath.ast.asm
|
package scietifik.kmath.asm
|
||||||
|
|
||||||
import scientifik.kmath.asm.asmField
|
import scientifik.kmath.asm.asmField
|
||||||
import scientifik.kmath.asm.asmRing
|
import scientifik.kmath.asm.asmRing
|
@ -1,4 +1,4 @@
|
|||||||
package scietifik.kmath.ast.asm
|
package scietifik.kmath.asm
|
||||||
|
|
||||||
import scientifik.kmath.asm.asmField
|
import scientifik.kmath.asm.asmField
|
||||||
import scientifik.kmath.expressions.invoke
|
import scientifik.kmath.expressions.invoke
|
@ -31,7 +31,7 @@ class ExpressionFieldTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun separateContext() {
|
fun separateContext() {
|
||||||
fun <T> FunctionalExpressionField<T>.expression(): Expression<T> {
|
fun <T> FunctionalExpressionField<T,*>.expression(): Expression<T> {
|
||||||
val x = variable("x")
|
val x = variable("x")
|
||||||
return x * x + 2 * x + one
|
return x * x + 2 * x + one
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ class ExpressionFieldTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun valueExpression() {
|
fun valueExpression() {
|
||||||
val expressionBuilder: FunctionalExpressionField<Double>.() -> Expression<Double> = {
|
val expressionBuilder: FunctionalExpressionField<Double,*>.() -> Expression<Double> = {
|
||||||
val x = variable("x")
|
val x = variable("x")
|
||||||
x * x + 2 * x + one
|
x * x + 2 * x + one
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user