Refactor staff evaluator
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user