Refactor Value and EvaluatorOutput models in order to get rid of optionals(?)
This commit is contained in:
@@ -4,7 +4,7 @@ import io.smnp.data.entity.Note
|
||||
import io.smnp.type.model.Value
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
enum class DataType(val kotlinType: KClass<out Any>?, val stringifier: (Any?) -> String) {
|
||||
enum class DataType(val kotlinType: KClass<out Any>, val stringifier: (Any) -> String) {
|
||||
INT(Int::class, { it.toString() }),
|
||||
FLOAT(Float::class, { it.toString() }),
|
||||
STRING(String::class, { it.toString() }),
|
||||
@@ -13,13 +13,9 @@ enum class DataType(val kotlinType: KClass<out Any>?, val stringifier: (Any?) ->
|
||||
NOTE(Note::class, { it.toString() }),
|
||||
BOOL(Boolean::class, { it.toString() }),
|
||||
TYPE(DataType::class, { it.toString() }),
|
||||
VOID(null, { "void" });
|
||||
|
||||
fun isInstance(value: Any?): Boolean {
|
||||
if(kotlinType == null) {
|
||||
return value == null
|
||||
}
|
||||
VOID(Unit::class, { "void" });
|
||||
|
||||
fun isInstance(value: Any): Boolean {
|
||||
return kotlinType.isInstance(value)
|
||||
}
|
||||
|
||||
@@ -30,17 +26,4 @@ enum class DataType(val kotlinType: KClass<out Any>?, val stringifier: (Any?) ->
|
||||
override fun toString(): String {
|
||||
return super.toString().toLowerCase()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun inference(value: Any?): DataType {
|
||||
if (value == null) {
|
||||
return VOID
|
||||
}
|
||||
|
||||
return values()
|
||||
.filter { it.kotlinType != null }
|
||||
.find { it.kotlinType!!.isInstance(value) }
|
||||
?: throw RuntimeException("Cannot inference type for '$value'")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ class Matcher(val type: DataType?, private val matcher: (Value) -> Boolean, priv
|
||||
return Matcher(
|
||||
DataType.MAP,
|
||||
{
|
||||
(it.value!! as Map<Value, Value>).entries.all { (k, v) ->
|
||||
(it.value as Map<Value, Value>).entries.all { (k, v) ->
|
||||
keyMatchers.any { m -> m.match(k) } && valueMatchers.any { m ->
|
||||
m.match(
|
||||
v
|
||||
@@ -70,7 +70,7 @@ class Matcher(val type: DataType?, private val matcher: (Value) -> Boolean, priv
|
||||
return matcher.match(value)
|
||||
}
|
||||
|
||||
return (value.value!! as List<Value>).all { match(it) }
|
||||
return (value.value as List<Value>).all { match(it) }
|
||||
}
|
||||
|
||||
return Matcher(
|
||||
|
||||
@@ -4,7 +4,7 @@ import io.smnp.data.entity.Note
|
||||
import io.smnp.error.ShouldNeverReachThisLineException
|
||||
import io.smnp.type.enumeration.DataType
|
||||
|
||||
data class Value(val type: DataType, val value: Any?, val properties: Map<String, Value> = emptyMap()) {
|
||||
data class Value(val type: DataType, val value: Any, val properties: Map<String, Value> = emptyMap()) {
|
||||
init {
|
||||
if (!type.isInstance(value)) {
|
||||
throw RuntimeException("'$value' is not of type $type")
|
||||
@@ -86,7 +86,7 @@ data class Value(val type: DataType, val value: Any?, val properties: Map<String
|
||||
}
|
||||
|
||||
fun void(): Value {
|
||||
return Value(DataType.VOID, null)
|
||||
return Value(DataType.VOID, Unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,6 @@ object FunctionEnvironmentProvider {
|
||||
index: Int
|
||||
) = (node.identifier as IdentifierNode).token.rawValue to
|
||||
if (index < actualArgs.size) actualArgs[index]
|
||||
else evaluator.evaluate(node.defaultValue, environment).value!!
|
||||
else evaluator.evaluate(node.defaultValue, environment).value
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class AccessOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val (lhsNode, _, rhsNode) = (node as AccessOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value
|
||||
|
||||
return when (rhsNode) {
|
||||
is IdentifierNode -> {
|
||||
@@ -33,7 +33,7 @@ class AccessOperatorEvaluator : Evaluator() {
|
||||
val (identifierNode, argsNode) = rhsNode
|
||||
val identifier = (identifierNode as IdentifierNode).token.rawValue
|
||||
val arguments =
|
||||
(argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value!! }
|
||||
(argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value }
|
||||
try {
|
||||
return EvaluatorOutput.value(environment.invokeMethod(lhs, identifier, arguments))
|
||||
} catch(e: MethodInvocationException) {
|
||||
|
||||
@@ -18,7 +18,7 @@ class AssignmentOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val (identifierNode, _, valueNode) = node as AssignmentOperatorNode
|
||||
val identifier = (identifierNode as IdentifierNode).token.rawValue
|
||||
val value = evaluator.evaluate(valueNode, environment).value!!
|
||||
val value = evaluator.evaluate(valueNode, environment).value
|
||||
|
||||
if (value.type == DataType.VOID) {
|
||||
throw PositionException(
|
||||
|
||||
@@ -18,7 +18,7 @@ class ConditionEvaluator : Evaluator() {
|
||||
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val (conditionNode, trueBranchNode, falseBranchNode) = (node as ConditionNode)
|
||||
val condition = expressionEvaluator.evaluate(conditionNode, environment).value!!
|
||||
val condition = expressionEvaluator.evaluate(conditionNode, environment).value
|
||||
|
||||
if (condition.type != DataType.BOOL) {
|
||||
throw PositionException(
|
||||
@@ -30,7 +30,7 @@ class ConditionEvaluator : Evaluator() {
|
||||
)
|
||||
}
|
||||
|
||||
if (condition.value!! as Boolean) {
|
||||
if (condition.value as Boolean) {
|
||||
return defaultEvaluator.evaluate(trueBranchNode, environment)
|
||||
} else if (falseBranchNode !is NoneNode) {
|
||||
return defaultEvaluator.evaluate(falseBranchNode, environment)
|
||||
|
||||
@@ -18,7 +18,7 @@ class FunctionCallEvaluator : Evaluator() {
|
||||
val evaluator = assert(ExpressionEvaluator(), "expression")
|
||||
val (identifierNode, argsNode) = node as FunctionCallNode
|
||||
val identifier = (identifierNode as IdentifierNode).token.rawValue
|
||||
val arguments = (argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value!! }
|
||||
val arguments = (argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value }
|
||||
|
||||
try {
|
||||
return EvaluatorOutput.value(environment.invokeFunction(identifier, arguments))
|
||||
|
||||
@@ -13,7 +13,7 @@ class ListEvaluator : Evaluator() {
|
||||
val atomEvaluator = ExpressionEvaluator()
|
||||
val items = (node as ListNode).items
|
||||
.map { atomEvaluator.evaluate(it, environment) }
|
||||
.map { it.value!! }
|
||||
.map { it.value }
|
||||
return EvaluatorOutput.value(Value.list(items))
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ class LogicOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val (lhsNode, opNode, rhsNode) = (node as LogicOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value
|
||||
val operator = (opNode as TokenNode).token.type
|
||||
|
||||
if (lhs.type != DataType.BOOL) {
|
||||
|
||||
@@ -19,7 +19,7 @@ class LoopEvaluator : Evaluator() {
|
||||
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val (iteratorNode, parametersNode, statementNode, filterNode) = node as LoopNode
|
||||
val iterator = expressionEvaluator.evaluate(iteratorNode, environment).value!!
|
||||
val iterator = expressionEvaluator.evaluate(iteratorNode, environment).value
|
||||
|
||||
environment.pushScope()
|
||||
val output = when (iterator.type) {
|
||||
@@ -159,7 +159,7 @@ class LoopEvaluator : Evaluator() {
|
||||
}
|
||||
|
||||
return output { outputs ->
|
||||
while (expressionEvaluator.evaluate(iteratorNode, environment).value!!.value as Boolean) {
|
||||
while (expressionEvaluator.evaluate(iteratorNode, environment).value.value as Boolean) {
|
||||
outputs.add(defaultEvaluator.evaluate(statementNode, environment))
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ class LoopEvaluator : Evaluator() {
|
||||
|
||||
private fun filter(filterNode: Node, environment: Environment): Boolean {
|
||||
if (filterNode != Node.NONE) {
|
||||
val condition = expressionEvaluator.evaluate(filterNode, environment).value!!
|
||||
val condition = expressionEvaluator.evaluate(filterNode, environment).value
|
||||
if (condition.type != BOOL) {
|
||||
throw PositionException(
|
||||
EnvironmentException(
|
||||
@@ -200,7 +200,7 @@ class LoopEvaluator : Evaluator() {
|
||||
evaluate(outputs)
|
||||
|
||||
return when {
|
||||
outputs.all { it.result == EvaluationResult.VALUE } -> EvaluatorOutput.value(Value.list(outputs.map { it.value!! }))
|
||||
outputs.all { it.result == EvaluationResult.VALUE } -> EvaluatorOutput.value(Value.list(outputs.map { it.value }))
|
||||
|
||||
// Disclaimer: It musn't be ok() because ExpressionEvaluator expects non-ok success output from each
|
||||
// of subevaluators.
|
||||
|
||||
@@ -20,7 +20,7 @@ class MapEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val value = (node as MapNode).items
|
||||
.map { it as MapEntryNode }
|
||||
.map { getKey(it.key, environment) to evaluator.evaluate(it.value, environment).value!! }
|
||||
.map { getKey(it.key, environment) to evaluator.evaluate(it.value, environment).value }
|
||||
.toMap()
|
||||
|
||||
return EvaluatorOutput.value(Value.map(value))
|
||||
@@ -29,7 +29,7 @@ class MapEvaluator : Evaluator() {
|
||||
private fun getKey(keyNode: Node, environment: Environment): Value {
|
||||
val key = when (keyNode) {
|
||||
is IdentifierNode -> Value.string(keyNode.token.rawValue)
|
||||
else -> evaluator.evaluate(keyNode, environment).value!!
|
||||
else -> evaluator.evaluate(keyNode, environment).value
|
||||
}
|
||||
|
||||
if (key.type !in listOf(BOOL, INT, NOTE, STRING)) {
|
||||
|
||||
@@ -19,7 +19,7 @@ class MinusOperatorEvaluator : Evaluator() {
|
||||
val operand = evaluator.evaluate(operandNode, environment)
|
||||
|
||||
return EvaluatorOutput.value(
|
||||
when (operand.value!!.type) {
|
||||
when (operand.value.type) {
|
||||
DataType.INT -> Value.int(-1 * operand.value.value as Int)
|
||||
DataType.FLOAT -> Value.float(-1.0f * operand.value.value as Float)
|
||||
DataType.STRING -> Value.string((operand.value.value as String).reversed())
|
||||
|
||||
@@ -16,7 +16,7 @@ class NotOperatorEvaluator : Evaluator() {
|
||||
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val (_, operandNode) = (node as NotOperatorNode)
|
||||
val operand = evaluator.evaluate(operandNode, environment).value!!
|
||||
val operand = evaluator.evaluate(operandNode, environment).value
|
||||
|
||||
if (operand.type != DataType.BOOL) {
|
||||
throw PositionException(
|
||||
|
||||
@@ -16,8 +16,8 @@ class PowerOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val (lhsNode, _, rhsNode) = (node as PowerOperatorNode)
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value
|
||||
|
||||
if (!lhs.type.isNumeric() || !rhs.type.isNumeric()) {
|
||||
throw PositionException(
|
||||
|
||||
@@ -19,8 +19,8 @@ class ProductOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val (lhsNode, opNode, rhsNode) = (node as ProductOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value
|
||||
val operator = (opNode as TokenNode).token.type
|
||||
|
||||
if (!lhs.type.isNumeric() || !rhs.type.isNumeric()) {
|
||||
|
||||
@@ -18,8 +18,8 @@ class RelationOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val (lhsNode, opNode, rhsNode) = (node as RelationOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value
|
||||
val operator = (opNode as TokenNode).token.rawValue
|
||||
|
||||
if (operator in listOf("==", "!=")) {
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.smnp.dsl.ast.model.node.ReturnNode
|
||||
import io.smnp.environment.Environment
|
||||
import io.smnp.evaluation.model.entity.EvaluatorOutput
|
||||
import io.smnp.evaluation.model.exception.Return
|
||||
import io.smnp.type.model.Value
|
||||
|
||||
class ReturnEvaluator : Evaluator() {
|
||||
override fun supportedNodes() = listOf(ReturnNode::class)
|
||||
@@ -13,7 +12,7 @@ class ReturnEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val (valueNode) = node as ReturnNode
|
||||
val value = evaluator.evaluate(valueNode, environment).value ?: Value.void()
|
||||
val value = evaluator.evaluate(valueNode, environment).value
|
||||
|
||||
// Disclaimer
|
||||
// Exception system usage to control program execution flow is really bad idea.
|
||||
|
||||
@@ -20,8 +20,8 @@ class SumOperatorEvaluator : Evaluator() {
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = ExpressionEvaluator()
|
||||
val (lhsNode, opNode, rhsNode) = (node as SumOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value
|
||||
val operator = (opNode as TokenNode).token.type
|
||||
|
||||
return EvaluatorOutput.value(
|
||||
@@ -37,9 +37,9 @@ class SumOperatorEvaluator : Evaluator() {
|
||||
return if (areNumeric(lhs, rhs))
|
||||
unify(lhs, rhs, int = { (l, r) -> Value.int(l + r) }, float = { (l, r) -> Value.float(l + r) })
|
||||
else if (lhs.type == DataType.STRING)
|
||||
Value.string(lhs.value!! as String + rhs.value.toString())
|
||||
Value.string(lhs.value as String + rhs.value.toString())
|
||||
else if (areLists(lhs, rhs))
|
||||
Value.list(lhs.value!! as List<Value> + rhs.value!! as List<Value>)
|
||||
Value.list(lhs.value as List<Value> + rhs.value as List<Value>)
|
||||
else throw PositionException(
|
||||
EnvironmentException(
|
||||
EvaluationException(
|
||||
|
||||
@@ -14,6 +14,6 @@ class ThrowEvaluator : Evaluator() {
|
||||
val valueNode = (node as ThrowNode).value
|
||||
val value = evaluator.evaluate(valueNode, environment)
|
||||
|
||||
throw CustomException(value.value!!.value.toString())
|
||||
throw CustomException(value.value.value.toString())
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,15 @@ package io.smnp.evaluation.model.entity
|
||||
import io.smnp.evaluation.model.enumeration.EvaluationResult
|
||||
import io.smnp.type.model.Value
|
||||
|
||||
class EvaluatorOutput private constructor(val result: EvaluationResult, val value: Value?) {
|
||||
class EvaluatorOutput private constructor(val result: EvaluationResult, val value: Value) {
|
||||
|
||||
override fun toString(): String {
|
||||
return "$result(${value ?: ""})"
|
||||
return "$result(${if(result == EvaluationResult.VALUE) value.toString() else ""})"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun ok(): EvaluatorOutput {
|
||||
return EvaluatorOutput(EvaluationResult.OK, null)
|
||||
return EvaluatorOutput(EvaluationResult.OK, Value.void())
|
||||
}
|
||||
|
||||
fun value(value: Value): EvaluatorOutput {
|
||||
@@ -19,7 +19,7 @@ class EvaluatorOutput private constructor(val result: EvaluationResult, val valu
|
||||
}
|
||||
|
||||
fun fail(): EvaluatorOutput {
|
||||
return EvaluatorOutput(EvaluationResult.FAILED, null)
|
||||
return EvaluatorOutput(EvaluationResult.FAILED, Value.void())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import io.smnp.type.model.Value
|
||||
class PrintlnFunction : Function("println") {
|
||||
override fun define(new: FunctionDefinitionTool) {
|
||||
new function vararg(allTypes()) body { _, (vararg) ->
|
||||
println((vararg.value!! as List<Value>).joinToString("") { it.stringify() })
|
||||
println((vararg.value as List<Value>).joinToString("") { it.stringify() })
|
||||
Value.void()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import io.smnp.type.model.Value
|
||||
class ReadFunction : Function("read") {
|
||||
override fun define(new: FunctionDefinitionTool) {
|
||||
new function simple(optional(ofType(STRING))) body { _, arguments ->
|
||||
arguments.getOrNull(0)?.let { print(it.value!!) }
|
||||
arguments.getOrNull(0)?.let { print(it.value) }
|
||||
Value.string(readLine() ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import io.smnp.type.model.Value
|
||||
class CharAtMethod : Method(ofType(STRING),"charAt") {
|
||||
override fun define(new: MethodDefinitionTool) {
|
||||
new method simple(ofType(INT)) body { _, obj, (index) ->
|
||||
Value.string((obj.value!! as String).getOrNull(index.value!! as Int)?.toString() ?: throw EvaluationException("Index '${index.value!!}' runs out of string bounds"))
|
||||
Value.string((obj.value as String).getOrNull(index.value as Int)?.toString() ?: throw EvaluationException("Index '${index.value}' runs out of string bounds"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ import io.smnp.type.model.Value
|
||||
class ListAccessMethod : Method(ofType(LIST), "get") {
|
||||
override fun define(new: MethodDefinitionTool) {
|
||||
new method simple(ofType(INT)) body { _, value, (index) ->
|
||||
val list = value.value!! as List<Value>
|
||||
val i = index.value!! as Int
|
||||
val list = value.value as List<Value>
|
||||
val i = index.value as Int
|
||||
|
||||
if(i >= list.size) {
|
||||
throw EvaluationException("Index '$i' runs out of array bounds")
|
||||
|
||||
@@ -12,8 +12,8 @@ import io.smnp.type.model.Value
|
||||
class MapAccessMethod : Method(ofType(MAP), "get") {
|
||||
override fun define(new: MethodDefinitionTool) {
|
||||
new method simple(allTypes()) body { _, obj, (key) ->
|
||||
val map = (obj.value!! as Map<Value, Value>)
|
||||
map[key] ?: throw EvaluationException("Key '${key.value!!}' not found")
|
||||
val map = (obj.value as Map<Value, Value>)
|
||||
map[key] ?: throw EvaluationException("Key '${key.value}' not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ class MidiFunction : Function("midi") {
|
||||
mapOfMatchers(ofType(INT), allTypes())
|
||||
) body { _, (config, lines) ->
|
||||
|
||||
val lines = (lines.value!! as List<Value>).map { it.value!! as List<Value> }
|
||||
val parameters = configParametersMap(config.value!!)
|
||||
val lines = (lines.value as List<Value>).map { it.value as List<Value> }
|
||||
val parameters = configParametersMap(config.value)
|
||||
MidiSequencer.playLines(lines, parameters)
|
||||
Value.void()
|
||||
}
|
||||
@@ -32,11 +32,11 @@ class MidiFunction : Function("midi") {
|
||||
mapOfMatchers(allTypes(), allTypes()),
|
||||
mapOfMatchers(ofType(INT), listOfMatchers(listOf(NOTE, INT, STRING)))
|
||||
) body { _, (config, channels) ->
|
||||
val channels = (channels.value!! as Map<Value, Value>).map { (key, value) ->
|
||||
key.value!! as Int to ((value.value!! as List<Value>).map { it.value!! as List<Value> })
|
||||
val channels = (channels.value as Map<Value, Value>).map { (key, value) ->
|
||||
key.value as Int to ((value.value as List<Value>).map { it.value as List<Value> })
|
||||
}.toMap()
|
||||
|
||||
val parameters = configParametersMap(config.value!!)
|
||||
val parameters = configParametersMap(config.value)
|
||||
MidiSequencer.playChannels(channels, parameters)
|
||||
|
||||
Value.void()
|
||||
@@ -45,10 +45,10 @@ class MidiFunction : Function("midi") {
|
||||
|
||||
private fun configParametersMap(config: Any): Map<String, Any> {
|
||||
return (config as Map<Value, Value>)
|
||||
.map { (key, value) -> key.value!! as String to value }
|
||||
.map { (key, value) -> key.value as String to value }
|
||||
.map { (key, value) ->
|
||||
key to when (key) {
|
||||
"bpm" -> if (value.type == INT) value.value!! else throw EvaluationException("Invalid parameter type: 'bpm' is supposed to be of int type")
|
||||
"bpm" -> if (value.type == INT) value.value else throw EvaluationException("Invalid parameter type: 'bpm' is supposed to be of int type")
|
||||
else -> value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ object MidiSequencer {
|
||||
NOTE -> {
|
||||
note(item, channel, noteOnTick, track)
|
||||
}
|
||||
INT -> noteOnTick + 4L * PPQ / (item.value!! as Int)
|
||||
INT -> noteOnTick + 4L * PPQ / (item.value as Int)
|
||||
STRING -> command(item, channel, noteOnTick, track)
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
}
|
||||
@@ -56,7 +56,7 @@ object MidiSequencer {
|
||||
}
|
||||
|
||||
private fun command(item: Value, channel: Int, beginTick: Long, track: Track): Long {
|
||||
val instruction = item.value!! as String
|
||||
val instruction = item.value as String
|
||||
if(instruction.isBlank()) {
|
||||
throw EvaluationException("Empty strings are not allowed here")
|
||||
}
|
||||
@@ -73,7 +73,7 @@ object MidiSequencer {
|
||||
}
|
||||
|
||||
private fun note(item: Value, channel: Int, noteOnTick: Long, track: Track): Long {
|
||||
val note = item.value!! as Note
|
||||
val note = item.value as Note
|
||||
val noteDuration = ((if (note.dot) 1.5 else 1.0) * 4L * PPQ / note.duration).toLong()
|
||||
val noteOffTick = noteOnTick + noteDuration
|
||||
track.add(noteOn(note, channel, noteOnTick))
|
||||
|
||||
@@ -13,7 +13,7 @@ class ExitFunction : Function("exit") {
|
||||
override fun define(new: FunctionDefinitionTool) {
|
||||
new function simple(optional(ofType(INT))) body { _, arguments ->
|
||||
val exitCode = arguments.getOrNull(0) ?: Value.int(0)
|
||||
exitProcess(exitCode.value!! as Int)
|
||||
exitProcess(exitCode.value as Int)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import io.smnp.type.model.Value
|
||||
class SleepFunction : Function("sleep") {
|
||||
override fun define(new: FunctionDefinitionTool) {
|
||||
new function simple(ofType(INT)) body { _, (milli) ->
|
||||
Thread.sleep((milli.value!! as Int).toLong())
|
||||
Thread.sleep((milli.value as Int).toLong())
|
||||
Value.void()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user