Refactor staff evaluator

This commit is contained in:
2020-03-19 15:16:42 +01:00
parent 2ab32b48fa
commit 53b92150c4

View File

@@ -21,34 +21,21 @@ class StaffEvaluator : Evaluator() {
var currentSignature: Fraction? = null var currentSignature: Fraction? = null
val list = measures.map { it as MeasureNode }.flatMap { measure -> val list = measures.map { it as MeasureNode }.flatMap { measure ->
val evaluatedMeasure = measure.items.mapNotNull { val evaluatedMeasure = measure.items.mapIndexedNotNull { index, it ->
when (it) { when (it) {
is TimeSignatureNode -> { is TimeSignatureNode -> {
assertTimeSignaturePosition(index, environment, it)
currentSignature = Fraction( currentSignature = Fraction(
(it.numerator as IntegerLiteralNode).token.value as Int, (it.numerator as IntegerLiteralNode).token.value as Int,
(it.denominator as IntegerLiteralNode).token.value as Int (it.denominator as IntegerLiteralNode).token.value as Int
) )
null null
} }
else -> evaluator.evaluate(it, environment).value else -> evaluator.evaluate(it, environment).value
} }
} }
val evaluatedSignature = calculateTimeSignature(evaluatedMeasure) assertTimeSignature(evaluatedMeasure, currentSignature, environment, measure)
currentSignature?.let {
if (evaluatedSignature != it) {
val simplified = evaluatedSignature.simplified
throw PositionException(
EnvironmentException(
EvaluationException("Invalid time signature: expected ${it.numerator}/${it.denominator}, got ${simplified.numerator}/${simplified.denominator}"),
environment
), measure.position
)
}
}
evaluatedMeasure evaluatedMeasure
} }
@@ -56,6 +43,42 @@ class StaffEvaluator : Evaluator() {
return EvaluatorOutput.value(Value.list(list)) return EvaluatorOutput.value(Value.list(list))
} }
private fun assertTimeSignaturePosition(
index: Int,
environment: Environment,
it: Node
) {
if (index != 0) {
throw PositionException(
EnvironmentException(
EvaluationException("Time signature can be placed only at the beginning of measure"),
environment
), it.position
)
}
}
private fun assertTimeSignature(
evaluatedMeasure: List<Value>,
currentSignature: Fraction?,
environment: Environment,
measure: MeasureNode
) {
val evaluatedSignature = calculateTimeSignature(evaluatedMeasure)
currentSignature?.let {
if (evaluatedSignature != it) {
val simplified = evaluatedSignature.simplified
throw PositionException(
EnvironmentException(
EvaluationException("Invalid time signature: expected ${it.numerator}/${it.denominator}, got ${simplified.numerator}/${simplified.denominator}"),
environment
), measure.position
)
}
}
}
private fun calculateTimeSignature(values: List<Value>): Fraction { private fun calculateTimeSignature(values: List<Value>): Fraction {
return values.fold(Fraction(0, 1)) { acc, value -> return values.fold(Fraction(0, 1)) { acc, value ->
acc + when (value.type) { acc + when (value.type) {