1
0
mirror of https://github.com/DanilaFe/abacus synced 2026-01-25 16:15:19 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
eb91a5b875 Fix a bug that made some same-priority implementations not convert. 2017-09-20 12:47:30 -07:00
fcd4694203 Merge pull request #32 from DanilaFe/promotion-exception
Add an exception thrown when promotion fails.
2017-09-20 12:16:00 -07:00
566831246c Add an exception thrown when promotion fails. 2017-09-20 12:06:06 -07:00
ad8a0a9b2a Merge pull request #29 from DanilaFe/fixes
Revert "Remove unnecessary nullability from parseString."
2017-09-16 03:05:20 -07:00
3 changed files with 34 additions and 13 deletions

View File

@@ -0,0 +1,24 @@
package org.nwapw.abacus.exception;
/**
* Exception thrown when a promotion fails.
*/
public class PromotionException extends AbacusException {
/**
* Creates a new PromotionException with the default message
* and no additional information.
*/
public PromotionException() {
this("");
}
/**
* Creates a new PromotionException with the given additional message.
* @param message the additional message to include with the error.
*/
public PromotionException(String message) {
super("Failed to promote number instances", message);
}
}

View File

@@ -1,6 +1,7 @@
package org.nwapw.abacus.number package org.nwapw.abacus.number
import org.nwapw.abacus.Abacus import org.nwapw.abacus.Abacus
import org.nwapw.abacus.exception.PromotionException
import org.nwapw.abacus.plugin.NumberImplementation import org.nwapw.abacus.plugin.NumberImplementation
import org.nwapw.abacus.plugin.PluginListener import org.nwapw.abacus.plugin.PluginListener
import org.nwapw.abacus.plugin.PluginManager import org.nwapw.abacus.plugin.PluginManager
@@ -45,27 +46,25 @@ class PromotionManager(val abacus: Abacus) : PluginListener {
* @param numbers the numbers to promote. * @param numbers the numbers to promote.
* @return the resulting promotion result. * @return the resulting promotion result.
*/ */
fun promote(vararg numbers: NumberInterface): PromotionResult? { fun promote(vararg numbers: NumberInterface): PromotionResult {
val pluginManager = abacus.pluginManager val pluginManager = abacus.pluginManager
val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) } val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) }
val highestPriority = implementations.sortedBy { it.priority }.last() val highestPriority = implementations.sortedBy { it.priority }.last()
return PromotionResult(items = numbers.map { return PromotionResult(items = numbers.map {
if(it.javaClass == highestPriority.implementation) it if(it.javaClass == highestPriority.implementation) it
else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority] else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority]
?.promote(it) ?: return null ?.promote(it) ?: throw PromotionException()
}.toTypedArray(), promotedTo = highestPriority) }.toTypedArray(), promotedTo = highestPriority)
} }
override fun onLoad(manager: PluginManager) { override fun onLoad(manager: PluginManager) {
val implementations = manager.allNumberImplementations.map { manager.numberImplementationFor(it) } val implementations = manager.allNumberImplementations.map { manager.numberImplementationFor(it) }
for((index, value) in implementations.withIndex()){ for(first in implementations) {
for(i in index until implementations.size){ for(second in implementations) {
val other = implementations[i] val promoteFrom = if(second.priority > first.priority) first else second
val promoteTo = if(second.priority > first.priority) second else first
val promoteFrom = if(other.priority > value.priority) value else other
val promoteTo = if(other.priority > value.priority) other else value
val path = computePathBetween(promoteFrom, promoteTo) val path = computePathBetween(promoteFrom, promoteTo)
computePaths.put(promoteFrom to promoteTo, path) computePaths[promoteFrom to promoteTo] = path
} }
} }
} }

View File

@@ -36,15 +36,13 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer<Nu
is NumberBinaryNode -> { is NumberBinaryNode -> {
val left = children[0] as NumberInterface val left = children[0] as NumberInterface
val right = children[1] as NumberInterface val right = children[1] as NumberInterface
val promotionResult = promotionManager.promote(left, right) ?: val promotionResult = promotionManager.promote(left, right)
throw EvaluationException("promotion failed.")
context.numberImplementation = promotionResult.promotedTo context.numberImplementation = promotionResult.promotedTo
abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items) abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items)
} }
is FunctionNode -> { is FunctionNode -> {
val promotionResult = promotionManager val promotionResult = promotionManager
.promote(*children.map { it as NumberInterface }.toTypedArray()) ?: .promote(*children.map { it as NumberInterface }.toTypedArray())
throw EvaluationException("promotion failed.")
context.numberImplementation = promotionResult.promotedTo context.numberImplementation = promotionResult.promotedTo
abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items) abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items)
} }