mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Проверка по типам вместо instanceof
This commit is contained in:
parent
a17bef18c5
commit
87637951a8
@ -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];
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -20,6 +20,11 @@ public class MapValue implements Value, Iterable<Map.Entry<Value, Value>> {
|
||||
public MapValue(Map<Value, Value> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int type() {
|
||||
return Types.MAP;
|
||||
}
|
||||
|
||||
public Value get(Value key) {
|
||||
return map.get(key);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
12
src/com/annimon/ownlang/lib/Types.java
Normal file
12
src/com/annimon/ownlang/lib/Types.java
Normal 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;
|
||||
}
|
@ -9,4 +9,6 @@ public interface Value {
|
||||
double asNumber();
|
||||
|
||||
String asString();
|
||||
|
||||
int type();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,13 +53,15 @@ public final class BinaryExpression implements Expression {
|
||||
final Value value1 = expr1.eval();
|
||||
final Value value2 = expr2.eval();
|
||||
|
||||
if (value1 instanceof StringValue) {
|
||||
return eval((StringValue) value1, value2);
|
||||
switch (value1.type()) {
|
||||
case Types.STRING:
|
||||
return eval((StringValue) value1, value2);
|
||||
case Types.ARRAY:
|
||||
return eval((ArrayValue) value1, value2);
|
||||
case Types.NUMBER:
|
||||
default:
|
||||
return eval(value1, value2);
|
||||
}
|
||||
if (value1 instanceof ArrayValue) {
|
||||
return eval((ArrayValue) value1, value2);
|
||||
}
|
||||
return eval(value1, value2);
|
||||
}
|
||||
|
||||
private Value eval(StringValue value1, Value value2) {
|
||||
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user