Проверка по типам вместо instanceof

This commit is contained in:
Victor 2016-01-09 13:51:44 +02:00
parent a17bef18c5
commit 87637951a8
12 changed files with 63 additions and 20 deletions

View File

@ -42,6 +42,11 @@ public final class ArrayValue implements Value, Iterable<Value> {
this(array.elements);
}
@Override
public int type() {
return Types.ARRAY;
}
public Value get(int index) {
return elements[index];
}

View File

@ -14,6 +14,11 @@ public final class FunctionValue implements Value {
this.value = value;
}
@Override
public int type() {
return Types.FUNCTION;
}
@Override
public double asNumber() {
throw new RuntimeException("Cannot cast function to number");

View File

@ -21,6 +21,11 @@ public class MapValue implements Value, Iterable<Map.Entry<Value, Value>> {
this.map = map;
}
@Override
public int type() {
return Types.MAP;
}
public Value get(Value key) {
return map.get(key);
}

View File

@ -19,6 +19,11 @@ public final class NumberValue implements Value {
this.value = value;
}
@Override
public int type() {
return Types.NUMBER;
}
@Override
public double asNumber() {
return value;

View File

@ -14,6 +14,11 @@ public final class StringValue implements Value {
this.value = value;
}
@Override
public int type() {
return Types.STRING;
}
@Override
public double asNumber() {
try {

View File

@ -0,0 +1,12 @@
package com.annimon.ownlang.lib;
public final class Types {
public static final int
OBJECT = 0,
NUMBER = 1,
STRING = 2,
ARRAY = 3,
MAP = 4,
FUNCTION = 5;
}

View File

@ -9,4 +9,6 @@ public interface Value {
double asNumber();
String asString();
int type();
}

View File

@ -2,6 +2,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.MapValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables;
import java.util.List;
@ -23,7 +24,7 @@ public final class ArrayAccessExpression implements Expression {
@Override
public Value eval() {
Value container = Variables.get(variable);
if (container instanceof ArrayValue) {
if (container.type() == Types.ARRAY) {
return getArray().get(lastIndex());
}
return consumeMap(container).get(indices.get(0).eval());
@ -47,19 +48,17 @@ public final class ArrayAccessExpression implements Expression {
}
private ArrayValue consumeArray(Value value) {
if (value instanceof ArrayValue) {
return (ArrayValue) value;
} else {
if (value.type() != Types.ARRAY) {
throw new RuntimeException("Array expected");
}
return (ArrayValue) value;
}
public MapValue consumeMap(Value value) {
if (value instanceof MapValue) {
return (MapValue) value;
} else {
if (value.type() != Types.MAP) {
throw new RuntimeException("Map expected");
}
return (MapValue) value;
}
@Override

View File

@ -1,6 +1,6 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables;
@ -21,7 +21,7 @@ public final class ArrayAssignmentStatement implements Statement {
@Override
public void execute() {
final Value container = Variables.get(array.variable);
if (container instanceof ArrayValue) {
if (container.type() == Types.ARRAY) {
array.getArray().set(array.lastIndex(), expression.eval());
return;
}

View File

@ -3,6 +3,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.StringValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
/**
@ -52,14 +53,16 @@ public final class BinaryExpression implements Expression {
final Value value1 = expr1.eval();
final Value value2 = expr2.eval();
if (value1 instanceof StringValue) {
switch (value1.type()) {
case Types.STRING:
return eval((StringValue) value1, value2);
}
if (value1 instanceof ArrayValue) {
case Types.ARRAY:
return eval((ArrayValue) value1, value2);
}
case Types.NUMBER:
default:
return eval(value1, value2);
}
}
private Value eval(StringValue value1, Value value2) {
final String string1 = value1.asString();
@ -81,7 +84,7 @@ public final class BinaryExpression implements Expression {
private Value eval(ArrayValue value1, Value value2) {
switch (operation) {
case LSHIFT:
if (!(value2 instanceof ArrayValue))
if (value2.type() != Types.ARRAY)
throw new RuntimeException("Cannot merge non array value to array");
return ArrayValue.merge(value1, (ArrayValue) value2);
case PUSH:

View File

@ -2,6 +2,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.StringValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
/**
@ -56,7 +57,7 @@ public final class ConditionalExpression implements Expression {
final Value value2 = expr2.eval();
double number1, number2;
if (value1 instanceof StringValue) {
if (value1.type() == Types.STRING) {
number1 = value1.asString().compareTo(value2.asString());
number2 = 0;
} else {

View File

@ -3,8 +3,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Function;
import com.annimon.ownlang.lib.FunctionValue;
import com.annimon.ownlang.lib.Functions;
import static com.annimon.ownlang.lib.Functions.isExists;
import com.annimon.ownlang.lib.UserDefinedFunction;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables;
import java.util.ArrayList;
@ -47,7 +46,9 @@ public final class FunctionalExpression implements Expression {
if (Functions.isExists(key)) return Functions.get(key);
if (Variables.isExists(key)) {
final Value value = Variables.get(key);
if (value instanceof FunctionValue) return ((FunctionValue)value).getValue();
if (value.type() == Types.FUNCTION) {
return ((FunctionValue)value).getValue();
}
}
throw new RuntimeException("Unknown function " + key);
}