Added support for mathematical expressions for numeric arguments in commands.

This only works for commands that have been ported over to the new command
framework.
This commit is contained in:
sk89q 2014-07-03 03:33:57 -07:00
parent 1f6e31dae8
commit 6c4a321d61

View File

@ -19,8 +19,16 @@
package com.sk89q.worldedit.util.command.binding; package com.sk89q.worldedit.util.command.binding;
import com.sk89q.worldedit.util.command.parametric.*; import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.util.command.parametric.ArgumentStack;
import com.sk89q.worldedit.util.command.parametric.BindingBehavior;
import com.sk89q.worldedit.util.command.parametric.BindingHelper;
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
import com.sk89q.worldedit.util.command.parametric.ParameterException;
import javax.annotation.Nullable;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
/** /**
@ -84,6 +92,35 @@ public final class PrimitiveBindings extends BindingHelper {
return context.nextBoolean(); return context.nextBoolean();
} }
/**
* Try to parse numeric input as either a number or a mathematical expression.
*
* @param input input
* @return a number
* @throws ParameterException thrown on parse error
*/
private @Nullable Double parseNumericInput(@Nullable String input) throws ParameterException {
if (input == null) {
return null;
}
try {
return Double.parseDouble(input);
} catch (NumberFormatException e1) {
try {
Expression expression = Expression.compile(input);
return expression.evaluate();
} catch (EvaluationException e) {
throw new ParameterException(String.format(
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
} catch (ExpressionException e) {
throw new ParameterException(String.format(
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
}
}
}
/** /**
* Gets a type from a {@link ArgumentStack}. * Gets a type from a {@link ArgumentStack}.
* *
@ -96,13 +133,15 @@ public final class PrimitiveBindings extends BindingHelper {
behavior = BindingBehavior.CONSUMES, behavior = BindingBehavior.CONSUMES,
consumedCount = 1, consumedCount = 1,
provideModifiers = true) provideModifiers = true)
public Integer getInteger(ArgumentStack context, Annotation[] modifiers) public Integer getInteger(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
throws ParameterException { Double v = parseNumericInput(context.next());
Integer v = context.nextInt();
if (v != null) { if (v != null) {
validate(v, modifiers); int intValue = v.intValue();
validate(intValue, modifiers);
return intValue;
} else {
return null;
} }
return v;
} }
/** /**
@ -117,8 +156,7 @@ public final class PrimitiveBindings extends BindingHelper {
behavior = BindingBehavior.CONSUMES, behavior = BindingBehavior.CONSUMES,
consumedCount = 1, consumedCount = 1,
provideModifiers = true) provideModifiers = true)
public Short getShort(ArgumentStack context, Annotation[] modifiers) public Short getShort(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
throws ParameterException {
Integer v = getInteger(context, modifiers); Integer v = getInteger(context, modifiers);
if (v != null) { if (v != null) {
return v.shortValue(); return v.shortValue();
@ -138,13 +176,14 @@ public final class PrimitiveBindings extends BindingHelper {
behavior = BindingBehavior.CONSUMES, behavior = BindingBehavior.CONSUMES,
consumedCount = 1, consumedCount = 1,
provideModifiers = true) provideModifiers = true)
public Double getDouble(ArgumentStack context, Annotation[] modifiers) public Double getDouble(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
throws ParameterException { Double v = parseNumericInput(context.next());
Double v = context.nextDouble();
if (v != null) { if (v != null) {
validate(v, modifiers); validate(v, modifiers);
}
return v; return v;
} else {
return null;
}
} }
/** /**
@ -159,8 +198,7 @@ public final class PrimitiveBindings extends BindingHelper {
behavior = BindingBehavior.CONSUMES, behavior = BindingBehavior.CONSUMES,
consumedCount = 1, consumedCount = 1,
provideModifiers = true) provideModifiers = true)
public Float getFloat(ArgumentStack context, Annotation[] modifiers) public Float getFloat(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
throws ParameterException {
Double v = getDouble(context, modifiers); Double v = getDouble(context, modifiers);
if (v != null) { if (v != null) {
return v.floatValue(); return v.floatValue();