Create base for future evaluators

This commit is contained in:
2020-03-07 12:52:30 +01:00
parent b01af589d9
commit f2494aa874
10 changed files with 185 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
package data.model.entity
package data.entity
import data.model.enumeration.Pitch
import data.enumeration.Pitch
class Note private constructor(val pitch: Pitch, val octave: Int, val duration: Int, val dot: Boolean) {
data class Builder(var pitch: Pitch = Pitch.A, var octave: Int = 4, var duration: Int = 4, var dot: Boolean = false) {

View File

@@ -0,0 +1,41 @@
package data.enumeration
import data.entity.Note
import kotlin.reflect.KClass
enum class DataType(val kotlinType: KClass<out Any>?) {
INT(Int::class),
FLOAT(Float::class),
STRING(String::class),
LIST(List::class),
MAP(Map::class),
NOTE(Note::class),
BOOL(Boolean::class),
TYPE(DataType::class),
VOID(null);
fun isInstance(value: Any?): Boolean {
if(kotlinType == null) {
return value == null
}
return kotlinType.isInstance(value)
}
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'")
}
}
}

View File

@@ -1,6 +1,4 @@
package data.model.enumeration
import java.lang.RuntimeException
package data.enumeration
enum class Pitch {
C, C_S, D, D_S, E, F, F_S, G, G_S, A, A_S, H;

View File

@@ -0,0 +1,67 @@
package data.model
import data.entity.Note
import data.enumeration.DataType
class Value private constructor(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")
}
}
override fun toString(): String {
return "$type($value)"
}
companion object {
fun int(value: Int): Value {
return Value(DataType.INT, value)
}
fun float(value: Float): Value {
return Value(DataType.FLOAT, value)
}
fun string(value: String): Value {
return Value(DataType.STRING, value, hashMapOf(
Pair("length", int(value.length))
))
}
fun list(value: List<Value>): Value {
return Value(DataType.LIST, value, hashMapOf(
Pair("size", int(value.size))
))
}
fun map(value: Map<Value, Value>): Value {
return Value(DataType.MAP, value, hashMapOf(
Pair("size", int(value.size)),
Pair("keys", list(value.keys.toList())),
Pair("values", list(value.values.toList()))
))
}
fun note(value: Note): Value {
return Value(DataType.NOTE, value, hashMapOf(
Pair("pitch", string(value.pitch.toString())),
Pair("octave", int(value.octave)),
Pair("duration", int(value.duration)),
Pair("dot", bool(value.dot))
))
}
fun bool(value: Boolean): Value {
return Value(DataType.BOOL, value)
}
fun type(value: DataType): Value {
return Value(DataType.TYPE, value)
}
fun void(): Value {
return Value(DataType.VOID, null)
}
}
}

View File

@@ -3,7 +3,7 @@ package dsl.ast.model.entity
import dsl.ast.model.enumeration.ParsingResult
import dsl.ast.model.node.Node
data class ParserOutput private constructor(val result: ParsingResult, val node: Node) {
class ParserOutput private constructor(val result: ParsingResult, val node: Node) {
fun map(mapper: (Node) -> Node): ParserOutput {
return if(result == ParsingResult.OK) ok(mapper(node)) else fail()
}

View File

@@ -1,7 +1,7 @@
package dsl.token.tokenizer
import data.model.entity.Note
import data.model.enumeration.Pitch
import data.entity.Note
import data.enumeration.Pitch
import dsl.token.model.entity.TokenizerOutput
import dsl.token.model.enumeration.TokenType

View File

@@ -0,0 +1,4 @@
package evaluation.environment
class Environment {
}

View File

@@ -0,0 +1,39 @@
package evaluation.evaluator
import dsl.ast.model.node.Node
import evaluation.environment.Environment
import evaluation.model.entity.EvaluatorOutput
import evaluation.model.enumeration.EvaluationResult
interface Evaluator {
fun evaluate(node: Node, environment: Environment): EvaluatorOutput
companion object {
fun forward(evaluator: Evaluator, vararg nodes: Node): Evaluator {
return object : Evaluator {
override fun evaluate(node: Node, environment: Environment): EvaluatorOutput {
if(nodes.map { it::class }.any { it.isInstance(node) }) {
return evaluator.evaluate(node, environment)
}
return EvaluatorOutput.fail()
}
}
}
fun oneOf(vararg evaluators: Evaluator): Evaluator {
return object : Evaluator {
override fun evaluate(node: Node, environment: Environment): EvaluatorOutput {
for(evaluator in evaluators) {
val output = evaluator.evaluate(node, environment)
if(output.result != EvaluationResult.FAILED) {
return output
}
}
return EvaluatorOutput.fail()
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
package evaluation.model.entity
import data.model.Value
import evaluation.model.enumeration.EvaluationResult
class EvaluatorOutput private constructor(val result: EvaluationResult, val value: Value?) {
companion object {
fun ok(): EvaluatorOutput {
return EvaluatorOutput(EvaluationResult.OK, null)
}
fun value(value: Value): EvaluatorOutput {
return EvaluatorOutput(EvaluationResult.VALUE, value)
}
fun fail(): EvaluatorOutput {
return EvaluatorOutput(EvaluationResult.FAILED, null)
}
}
}

View File

@@ -0,0 +1,7 @@
package evaluation.model.enumeration
enum class EvaluationResult {
OK,
VALUE,
FAILED
}