mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44: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);
|
this(array.elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int type() {
|
||||||
|
return Types.ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
public Value get(int index) {
|
public Value get(int index) {
|
||||||
return elements[index];
|
return elements[index];
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,11 @@ public final class FunctionValue implements Value {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int type() {
|
||||||
|
return Types.FUNCTION;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double asNumber() {
|
public double asNumber() {
|
||||||
throw new RuntimeException("Cannot cast function to number");
|
throw new RuntimeException("Cannot cast function to number");
|
||||||
|
@ -21,6 +21,11 @@ public class MapValue implements Value, Iterable<Map.Entry<Value, Value>> {
|
|||||||
this.map = map;
|
this.map = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int type() {
|
||||||
|
return Types.MAP;
|
||||||
|
}
|
||||||
|
|
||||||
public Value get(Value key) {
|
public Value get(Value key) {
|
||||||
return map.get(key);
|
return map.get(key);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,11 @@ public final class NumberValue implements Value {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int type() {
|
||||||
|
return Types.NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double asNumber() {
|
public double asNumber() {
|
||||||
return value;
|
return value;
|
||||||
|
@ -14,6 +14,11 @@ public final class StringValue implements Value {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int type() {
|
||||||
|
return Types.STRING;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double asNumber() {
|
public double asNumber() {
|
||||||
try {
|
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();
|
double asNumber();
|
||||||
|
|
||||||
String asString();
|
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.ArrayValue;
|
||||||
import com.annimon.ownlang.lib.MapValue;
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
import com.annimon.ownlang.lib.Variables;
|
import com.annimon.ownlang.lib.Variables;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -23,7 +24,7 @@ public final class ArrayAccessExpression implements Expression {
|
|||||||
@Override
|
@Override
|
||||||
public Value eval() {
|
public Value eval() {
|
||||||
Value container = Variables.get(variable);
|
Value container = Variables.get(variable);
|
||||||
if (container instanceof ArrayValue) {
|
if (container.type() == Types.ARRAY) {
|
||||||
return getArray().get(lastIndex());
|
return getArray().get(lastIndex());
|
||||||
}
|
}
|
||||||
return consumeMap(container).get(indices.get(0).eval());
|
return consumeMap(container).get(indices.get(0).eval());
|
||||||
@ -47,19 +48,17 @@ public final class ArrayAccessExpression implements Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ArrayValue consumeArray(Value value) {
|
private ArrayValue consumeArray(Value value) {
|
||||||
if (value instanceof ArrayValue) {
|
if (value.type() != Types.ARRAY) {
|
||||||
return (ArrayValue) value;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Array expected");
|
throw new RuntimeException("Array expected");
|
||||||
}
|
}
|
||||||
|
return (ArrayValue) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapValue consumeMap(Value value) {
|
public MapValue consumeMap(Value value) {
|
||||||
if (value instanceof MapValue) {
|
if (value.type() != Types.MAP) {
|
||||||
return (MapValue) value;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Map expected");
|
throw new RuntimeException("Map expected");
|
||||||
}
|
}
|
||||||
|
return (MapValue) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.annimon.ownlang.parser.ast;
|
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.Value;
|
||||||
import com.annimon.ownlang.lib.Variables;
|
import com.annimon.ownlang.lib.Variables;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ public final class ArrayAssignmentStatement implements Statement {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
final Value container = Variables.get(array.variable);
|
final Value container = Variables.get(array.variable);
|
||||||
if (container instanceof ArrayValue) {
|
if (container.type() == Types.ARRAY) {
|
||||||
array.getArray().set(array.lastIndex(), expression.eval());
|
array.getArray().set(array.lastIndex(), expression.eval());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
import com.annimon.ownlang.lib.ArrayValue;
|
import com.annimon.ownlang.lib.ArrayValue;
|
||||||
import com.annimon.ownlang.lib.NumberValue;
|
import com.annimon.ownlang.lib.NumberValue;
|
||||||
import com.annimon.ownlang.lib.StringValue;
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,13 +53,15 @@ public final class BinaryExpression implements Expression {
|
|||||||
final Value value1 = expr1.eval();
|
final Value value1 = expr1.eval();
|
||||||
final Value value2 = expr2.eval();
|
final Value value2 = expr2.eval();
|
||||||
|
|
||||||
if (value1 instanceof StringValue) {
|
switch (value1.type()) {
|
||||||
return eval((StringValue) value1, value2);
|
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) {
|
private Value eval(StringValue value1, Value value2) {
|
||||||
@ -81,7 +84,7 @@ public final class BinaryExpression implements Expression {
|
|||||||
private Value eval(ArrayValue value1, Value value2) {
|
private Value eval(ArrayValue value1, Value value2) {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case LSHIFT:
|
case LSHIFT:
|
||||||
if (!(value2 instanceof ArrayValue))
|
if (value2.type() != Types.ARRAY)
|
||||||
throw new RuntimeException("Cannot merge non array value to array");
|
throw new RuntimeException("Cannot merge non array value to array");
|
||||||
return ArrayValue.merge(value1, (ArrayValue) value2);
|
return ArrayValue.merge(value1, (ArrayValue) value2);
|
||||||
case PUSH:
|
case PUSH:
|
||||||
|
@ -2,6 +2,7 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
|
|
||||||
import com.annimon.ownlang.lib.NumberValue;
|
import com.annimon.ownlang.lib.NumberValue;
|
||||||
import com.annimon.ownlang.lib.StringValue;
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +57,7 @@ public final class ConditionalExpression implements Expression {
|
|||||||
final Value value2 = expr2.eval();
|
final Value value2 = expr2.eval();
|
||||||
|
|
||||||
double number1, number2;
|
double number1, number2;
|
||||||
if (value1 instanceof StringValue) {
|
if (value1.type() == Types.STRING) {
|
||||||
number1 = value1.asString().compareTo(value2.asString());
|
number1 = value1.asString().compareTo(value2.asString());
|
||||||
number2 = 0;
|
number2 = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,8 +3,7 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
import com.annimon.ownlang.lib.Function;
|
import com.annimon.ownlang.lib.Function;
|
||||||
import com.annimon.ownlang.lib.FunctionValue;
|
import com.annimon.ownlang.lib.FunctionValue;
|
||||||
import com.annimon.ownlang.lib.Functions;
|
import com.annimon.ownlang.lib.Functions;
|
||||||
import static com.annimon.ownlang.lib.Functions.isExists;
|
import com.annimon.ownlang.lib.Types;
|
||||||
import com.annimon.ownlang.lib.UserDefinedFunction;
|
|
||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
import com.annimon.ownlang.lib.Variables;
|
import com.annimon.ownlang.lib.Variables;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -47,7 +46,9 @@ public final class FunctionalExpression implements Expression {
|
|||||||
if (Functions.isExists(key)) return Functions.get(key);
|
if (Functions.isExists(key)) return Functions.get(key);
|
||||||
if (Variables.isExists(key)) {
|
if (Variables.isExists(key)) {
|
||||||
final Value value = Variables.get(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);
|
throw new RuntimeException("Unknown function " + key);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user