Skip to content

Commit 0a33671

Browse files
authored
Merge pull request #53 from javecs/feature/plugin
ユーザー関数をプラグインして、実行する機能を追加しました。
2 parents af32b18 + f4cf426 commit 0a33671

6 files changed

Lines changed: 32 additions & 5 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ plugins {
1616
}
1717

1818
group 'xyz.javecs.tools'
19-
version '0.1.11'
19+
version '0.2.1'
2020

2121
apply plugin: 'kotlin'
2222
apply plugin: 'antlr'

src/main/kotlin/xyz/javecs/tools/expr/BuiltIn.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ internal fun constant() = HashMap<String, Double>().apply {
55
put("e", Math.E)
66
}
77

8-
internal fun invoke(name: String, args: ArrayList<Double>) = when (name) {
8+
internal fun invoke(name: String, args: Array<Double>) = when (name) {
99
"sin" -> Math.sin(args[0])
1010
"cos" -> Math.cos(args[0])
1111
"tan" -> Math.tan(args[0])

src/main/kotlin/xyz/javecs/tools/expr/Calculator.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Calculator(expressions: Array<String> = emptyArray()) : EvalContext {
66
private val evaluator = EvalVisitor(this)
77
private val variables = HashMap<String, Double>()
88
private val constants = constant()
9+
private val functions = HashMap<String, Function>()
910
private var expression = Expression()
1011
var value: Number = expression.value
1112
get() = expression.getValue()
@@ -14,6 +15,14 @@ class Calculator(expressions: Array<String> = emptyArray()) : EvalContext {
1415
expressions.forEach { eval(it) }
1516
}
1617

18+
private fun callFunction(name: String, args: Array<Double>): Double {
19+
return if (functions.containsKey(name)) {
20+
functions[name]!!.call(args)
21+
} else {
22+
invoke(name.toLowerCase(), args)
23+
}
24+
}
25+
1726
fun eval(expr: String = ""): Calculator {
1827
expression = when (expr.isEmpty()) {
1928
true -> expression
@@ -31,9 +40,13 @@ class Calculator(expressions: Array<String> = emptyArray()) : EvalContext {
3140
expression = Expression()
3241
}
3342

43+
fun plugin(function: Function) {
44+
functions.put(function.name, function)
45+
}
46+
3447
override fun toString() = expression.toString()
3548
override fun isConstant(name: String) = constants.contains(name.toLowerCase())
36-
override fun call(name: String, args: ArrayList<Double>) = invoke(name.toLowerCase(), args)
49+
override fun call(name: String, args: Array<Double>) = callFunction(name, args)
3750
override fun get(name: String) = constants.getOrDefault(name.toLowerCase(), variables.getOrDefault(name, Double.NaN))
3851
override fun put(name:String, value: Double) = when (isConstant(name)) {
3952
true -> Double.NaN

src/main/kotlin/xyz/javecs/tools/expr/EvalContext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ package xyz.javecs.tools.expr
33
internal interface EvalContext {
44
fun get(name: String): Double
55
fun put(name:String, value: Double): Double
6-
fun call(name: String, args: ArrayList<Double>): Double
6+
fun call(name: String, args: Array<Double>): Double
77
fun isConstant(name: String): Boolean
88
}

src/main/kotlin/xyz/javecs/tools/expr/EvalVisitor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ internal class EvalVisitor(val context: EvalContext) : ExprBaseVisitor<Expressio
4040
val func = ctx!!.ID().text
4141
val args = ArrayList<Double>()
4242
ctx.expr().mapTo(args) { visit(it).value }
43-
return Expression(value = context.call(func, args))
43+
return Expression(value = context.call(func, args.toTypedArray()))
4444
}
4545

4646
override fun visitConstant(ctx: ExprParser.ConstantContext?): Expression {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package xyz.javecs.tools.expr.test.kotlin
2+
3+
import kotlin.test.assertEquals
4+
import org.junit.Test
5+
import xyz.javecs.tools.expr.Calculator
6+
import xyz.javecs.tools.expr.Function
7+
8+
class CalculatorPluginTest {
9+
@Test fun plugin1() {
10+
val calc = Calculator()
11+
calc.plugin(Function("f(x,y)", arrayOf("x + y")))
12+
assertEquals(3, calc.eval("f(1,2)").value)
13+
}
14+
}

0 commit comments

Comments
 (0)