Расширенные исключения

This commit is contained in:
Victor 2016-01-19 13:38:56 +02:00
parent 5970d20a61
commit b194a7b9b9
36 changed files with 209 additions and 58 deletions

View File

@ -0,0 +1,11 @@
package com.annimon.ownlang.exceptions;
public final class ArgumentsMismatchException extends RuntimeException {
public ArgumentsMismatchException() {
}
public ArgumentsMismatchException(String message) {
super(message);
}
}

View File

@ -1,4 +1,4 @@
package com.annimon.ownlang.parser; package com.annimon.ownlang.exceptions;
/** /**
* *

View File

@ -0,0 +1,8 @@
package com.annimon.ownlang.exceptions;
public final class OperationIsNotSupportedException extends RuntimeException {
public OperationIsNotSupportedException(Object operation) {
super("Operation " + operation + " is not supported");
}
}

View File

@ -1,4 +1,4 @@
package com.annimon.ownlang.parser; package com.annimon.ownlang.exceptions;
/** /**
* *

View File

@ -0,0 +1,11 @@
package com.annimon.ownlang.exceptions;
public final class PatternMatchingException extends RuntimeException {
public PatternMatchingException() {
}
public PatternMatchingException(String message) {
super(message);
}
}

View File

@ -0,0 +1,8 @@
package com.annimon.ownlang.exceptions;
public final class TypeException extends RuntimeException {
public TypeException(String message) {
super(message);
}
}

View File

@ -0,0 +1,15 @@
package com.annimon.ownlang.exceptions;
public final class UnknownFunctionException extends RuntimeException {
private final String functionName;
public UnknownFunctionException(String name) {
super("Unknown function " + name);
this.functionName = name;
}
public String getFunctionName() {
return functionName;
}
}

View File

@ -0,0 +1,15 @@
package com.annimon.ownlang.exceptions;
public final class VariableDoesNotExistsException extends RuntimeException {
private final String variable;
public VariableDoesNotExistsException(String variable) {
super("Variable " + variable + " does not exists");
this.variable = variable;
}
public String getVariable() {
return variable;
}
}

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib; package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.TypeException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
@ -61,7 +62,7 @@ public final class ArrayValue implements Value, Iterable<Value> {
@Override @Override
public double asNumber() { public double asNumber() {
throw new RuntimeException("Cannot cast array to number"); throw new TypeException("Cannot cast array to number");
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib; package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.TypeException;
import java.util.Objects; import java.util.Objects;
/** /**
@ -23,7 +24,7 @@ public final class FunctionValue implements Value {
@Override @Override
public double asNumber() { public double asNumber() {
throw new RuntimeException("Cannot cast function to number"); throw new TypeException("Cannot cast function to number");
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib; package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.UnknownFunctionException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -20,7 +21,7 @@ public final class Functions {
} }
public static Function get(String key) { public static Function get(String key) {
if (!isExists(key)) throw new RuntimeException("Unknown function " + key); if (!isExists(key)) throw new UnknownFunctionException(key);
return functions.get(key); return functions.get(key);
} }

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib; package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.TypeException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -46,7 +47,7 @@ public class MapValue implements Value, Iterable<Map.Entry<Value, Value>> {
@Override @Override
public double asNumber() { public double asNumber() {
throw new RuntimeException("Cannot cast map to number"); throw new TypeException("Cannot cast map to number");
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib; package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.parser.ast.ReturnStatement; import com.annimon.ownlang.parser.ast.ReturnStatement;
import com.annimon.ownlang.parser.ast.Statement; import com.annimon.ownlang.parser.ast.Statement;
import java.util.List; import java.util.List;
@ -30,7 +31,7 @@ public final class UserDefinedFunction implements Function {
@Override @Override
public Value execute(Value... values) { public Value execute(Value... values) {
final int size = values.length; final int size = values.length;
if (size != getArgsCount()) throw new RuntimeException("Args count mismatch"); if (size != getArgsCount()) throw new ArgumentsMismatchException("Arguments count mismatch");
try { try {
Variables.push(); Variables.push();

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib.modules; package com.annimon.ownlang.lib.modules;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
@ -89,7 +90,7 @@ public final class canvas implements Module {
private static Function intConsumer4Convert(IntConsumer4 consumer) { private static Function intConsumer4Convert(IntConsumer4 consumer) {
return args -> { return args -> {
if (args.length != 4) throw new RuntimeException("Four args expected"); if (args.length != 4) throw new ArgumentsMismatchException("Four args expected");
int x = (int) args[0].asNumber(); int x = (int) args[0].asNumber();
int y = (int) args[1].asNumber(); int y = (int) args[1].asNumber();
int w = (int) args[2].asNumber(); int w = (int) args[2].asNumber();
@ -186,7 +187,7 @@ public final class canvas implements Module {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length != 3) throw new RuntimeException("Three args expected"); if (args.length != 3) throw new ArgumentsMismatchException("Three args expected");
int x = (int) args[1].asNumber(); int x = (int) args[1].asNumber();
int y = (int) args[2].asNumber(); int y = (int) args[2].asNumber();
graphics.drawString(args[0].asString(), x, y); graphics.drawString(args[0].asString(), x, y);

View File

@ -0,0 +1,55 @@
package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.lib.*;
import java.util.Map;
public final class functional_map implements Function {
@Override
public Value execute(Value... args) {
if (args.length < 2) throw new RuntimeException("At least two args expected");
final Value container = args[0];
if (container.type() == Types.ARRAY) {
if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg");
}
final Function mapper = ((FunctionValue) args[1]).getValue();
return mapArray((ArrayValue) container, mapper);
}
if (container.type() == Types.MAP) {
if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg");
}
if (args[2].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in third arg");
}
final Function keyMapper = ((FunctionValue) args[1]).getValue();
final Function valueMapper = ((FunctionValue) args[2]).getValue();
return mapMap((MapValue) container, keyMapper, valueMapper);
}
throw new RuntimeException("Invalid first argument. Array or map exprected");
}
private Value mapArray(ArrayValue array, Function mapper) {
final int size = array.size();
final ArrayValue result = new ArrayValue(size);
for (int i = 0; i < size; i++) {
result.set(i, mapper.execute(array.get(i)));
}
return result;
}
private Value mapMap(MapValue map, Function keyMapper, Function valueMapper) {
final MapValue result = new MapValue(map.size());
for (Map.Entry<Value, Value> element : map) {
final Value newKey = keyMapper.execute(element.getKey());
final Value newValue = valueMapper.execute(element.getValue());
result.set(newKey, newValue);
}
return result;
}
}

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -10,10 +12,10 @@ public final class functional_filter implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length < 2) throw new RuntimeException("At least two args expected"); if (args.length < 2) throw new ArgumentsMismatchException("At least two args expected");
if (args[1].type() != Types.FUNCTION) { if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg"); throw new TypeException("Function expected in second arg");
} }
final Value container = args[0]; final Value container = args[0];
final Function consumer = ((FunctionValue) args[1]).getValue(); final Function consumer = ((FunctionValue) args[1]).getValue();
@ -25,7 +27,7 @@ public final class functional_filter implements Function {
return filterMap((MapValue) container, consumer); return filterMap((MapValue) container, consumer);
} }
throw new RuntimeException("Invalid first argument. Array or map exprected"); throw new TypeException("Invalid first argument. Array or map exprected");
} }
private Value filterArray(ArrayValue array, Function predicate) { private Value filterArray(ArrayValue array, Function predicate) {

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.Map; import java.util.Map;
@ -8,10 +10,10 @@ public final class functional_foreach implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length != 2) throw new RuntimeException("Two args expected"); if (args.length != 2) throw new ArgumentsMismatchException("Two args expected");
if (args[1].type() != Types.FUNCTION) { if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg"); throw new TypeException("Function expected in second arg");
} }
final Value container = args[0]; final Value container = args[0];
final Function consumer = ((FunctionValue) args[1]).getValue(); final Function consumer = ((FunctionValue) args[1]).getValue();
@ -29,6 +31,6 @@ public final class functional_foreach implements Function {
} }
return NumberValue.ZERO; return NumberValue.ZERO;
} }
throw new RuntimeException("Invalid first argument. Array or map exprected"); throw new TypeException("Invalid first argument. Array or map exprected");
} }
} }

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.Map; import java.util.Map;
@ -8,12 +10,12 @@ public final class functional_map implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length < 2) throw new RuntimeException("At least two args expected"); if (args.length < 2) throw new ArgumentsMismatchException("At least two args expected");
final Value container = args[0]; final Value container = args[0];
if (container.type() == Types.ARRAY) { if (container.type() == Types.ARRAY) {
if (args[1].type() != Types.FUNCTION) { if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg"); throw new TypeException("Function expected in second arg");
} }
final Function mapper = ((FunctionValue) args[1]).getValue(); final Function mapper = ((FunctionValue) args[1]).getValue();
return mapArray((ArrayValue) container, mapper); return mapArray((ArrayValue) container, mapper);
@ -21,17 +23,17 @@ public final class functional_map implements Function {
if (container.type() == Types.MAP) { if (container.type() == Types.MAP) {
if (args[1].type() != Types.FUNCTION) { if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg"); throw new TypeException("Function expected in second arg");
} }
if (args[2].type() != Types.FUNCTION) { if (args[2].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in third arg"); throw new TypeException("Function expected in third arg");
} }
final Function keyMapper = ((FunctionValue) args[1]).getValue(); final Function keyMapper = ((FunctionValue) args[1]).getValue();
final Function valueMapper = ((FunctionValue) args[2]).getValue(); final Function valueMapper = ((FunctionValue) args[2]).getValue();
return mapMap((MapValue) container, keyMapper, valueMapper); return mapMap((MapValue) container, keyMapper, valueMapper);
} }
throw new RuntimeException("Invalid first argument. Array or map exprected"); throw new TypeException("Invalid first argument. Array or map exprected");
} }
private Value mapArray(ArrayValue array, Function mapper) { private Value mapArray(ArrayValue array, Function mapper) {

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.Map; import java.util.Map;
@ -8,10 +10,10 @@ public final class functional_reduce implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length != 3) throw new RuntimeException("Three args expected"); if (args.length != 3) throw new ArgumentsMismatchException("Three args expected");
if (args[2].type() != Types.FUNCTION) { if (args[2].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in third arg"); throw new TypeException("Function expected in third arg");
} }
final Value container = args[0]; final Value container = args[0];
final Value identity = args[1]; final Value identity = args[1];
@ -32,6 +34,6 @@ public final class functional_reduce implements Function {
} }
return result; return result;
} }
throw new RuntimeException("Invalid first argument. Array or map exprected"); throw new TypeException("Invalid first argument. Array or map exprected");
} }
} }

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -49,7 +51,7 @@ public final class http_http implements Function {
case 4: // http(url, method, params, callback) case 4: // http(url, method, params, callback)
if (args[3].type() != Types.FUNCTION) { if (args[3].type() != Types.FUNCTION) {
throw new RuntimeException("Fourth arg must be a function callback"); throw new TypeException("Fourth arg must be a function callback");
} }
url = args[0].asString(); url = args[0].asString();
method = args[1].asString(); method = args[1].asString();
@ -57,17 +59,17 @@ public final class http_http implements Function {
case 5: // http(url, method, params, headerParams, callback) case 5: // http(url, method, params, headerParams, callback)
if (args[3].type() != Types.MAP) { if (args[3].type() != Types.MAP) {
throw new RuntimeException("Third arg must be a map"); throw new TypeException("Third arg must be a map");
} }
if (args[4].type() != Types.FUNCTION) { if (args[4].type() != Types.FUNCTION) {
throw new RuntimeException("Fifth arg must be a function callback"); throw new TypeException("Fifth arg must be a function callback");
} }
url = args[0].asString(); url = args[0].asString();
method = args[1].asString(); method = args[1].asString();
return process(url, method, args[2], (MapValue) args[3], (FunctionValue) args[4]); return process(url, method, args[2], (MapValue) args[3], (FunctionValue) args[4]);
default: default:
throw new RuntimeException("Wrong number of arguments"); throw new ArgumentsMismatchException("Wrong number of arguments");
} }
} }

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.lib.Function;
import com.annimon.ownlang.lib.StringValue; import com.annimon.ownlang.lib.StringValue;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
@ -10,7 +11,7 @@ public final class http_urlencode implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length == 0) throw new RuntimeException("At least one arg expected"); if (args.length == 0) throw new ArgumentsMismatchException("At least one arg expected");
String charset = "UTF-8"; String charset = "UTF-8";
if (args.length >= 2) { if (args.length >= 2) {

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.Iterator; import java.util.Iterator;
import org.json.*; import org.json.*;
@ -8,7 +9,7 @@ public final class json_decode implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length != 1) throw new RuntimeException("One argument expected"); if (args.length != 1) throw new ArgumentsMismatchException("One argument expected");
try { try {
final String jsonRaw = args[0].asString(); final String jsonRaw = args[0].asString();
final Object root = new JSONTokener(jsonRaw).nextValue(); final Object root = new JSONTokener(jsonRaw).nextValue();

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.Map; import java.util.Map;
import org.json.*; import org.json.*;
@ -8,7 +9,7 @@ public final class json_encode implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length != 1) throw new RuntimeException("One argument expected"); if (args.length != 1) throw new ArgumentsMismatchException("One argument expected");
try { try {
final Object root = process(args[0]); final Object root = process(args[0]);
final String jsonRaw = JSONObject.valueToString(root); final String jsonRaw = JSONObject.valueToString(root);

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.Map; import java.util.Map;
@ -8,9 +10,9 @@ public final class std_foreach implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length != 2) return NumberValue.ZERO; if (args.length != 2) throw new ArgumentsMismatchException("Two arguments expected");
if (args[1].type() != Types.FUNCTION) return NumberValue.ZERO; if (args[1].type() != Types.FUNCTION) throw new TypeException("Second arg must be a function");
final Function function = ((FunctionValue) args[1]).getValue(); final Function function = ((FunctionValue) args[1]).getValue();
final Value container = args[0]; final Value container = args[0];
if (container.type() == Types.ARRAY) { if (container.type() == Types.ARRAY) {
@ -27,6 +29,6 @@ public final class std_foreach implements Function {
} }
return NumberValue.ZERO; return NumberValue.ZERO;
} }
return NumberValue.ZERO; throw new TypeException("First arg must be an array or map");
} }
} }

View File

@ -1,12 +1,13 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
public final class std_length implements Function { public final class std_length implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length == 0) throw new RuntimeException("At least one arg expected"); if (args.length == 0) throw new ArgumentsMismatchException("At least one arg expected");
final Value val = args[0]; final Value val = args[0];
int length; int length;

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.lib.Function;
import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
@ -8,12 +9,12 @@ public final class std_sleep implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
if (args.length == 1) { if (args.length != 1) throw new ArgumentsMismatchException("One argument expected");
try {
Thread.sleep((long) args[0].asNumber()); try {
} catch (InterruptedException ex) { Thread.sleep((long) args[0].asNumber());
Thread.currentThread().interrupt(); } catch (InterruptedException ex) {
} Thread.currentThread().interrupt();
} }
return NumberValue.ZERO; return NumberValue.ZERO;
} }

View File

@ -1,11 +1,7 @@
package com.annimon.ownlang.lib.modules.functions; package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.FunctionValue; import com.annimon.ownlang.lib.*;
import com.annimon.ownlang.lib.Functions;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
public final class std_thread implements Function { public final class std_thread implements Function {
@ -13,7 +9,7 @@ public final class std_thread implements Function {
public Value execute(Value... args) { public Value execute(Value... args) {
// Создаём новый поток и передаём параметры, если есть. // Создаём новый поток и передаём параметры, если есть.
// Функция может передаваться как напрямую, так и по имени // Функция может передаваться как напрямую, так и по имени
if (args.length == 0) throw new RuntimeException("At least one arg expected"); if (args.length == 0) throw new ArgumentsMismatchException("At least one arg expected");
Function body; Function body;
if (args[0].type() == Types.FUNCTION) { if (args[0].type() == Types.FUNCTION) {

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.lib.modules; package com.annimon.ownlang.lib.modules;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.function.DoubleBinaryOperator; import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleFunction; import java.util.function.DoubleFunction;
@ -57,14 +58,14 @@ public final class math implements Module {
private static Function functionConvert(DoubleUnaryOperator op) { private static Function functionConvert(DoubleUnaryOperator op) {
return args -> { return args -> {
if (args.length != 1) throw new RuntimeException("One arg expected"); if (args.length != 1) throw new ArgumentsMismatchException("One arg expected");
return doubleToNumber.apply(op.applyAsDouble(args[0].asNumber())); return doubleToNumber.apply(op.applyAsDouble(args[0].asNumber()));
}; };
} }
private static Function biFunctionConvert(DoubleBinaryOperator op) { private static Function biFunctionConvert(DoubleBinaryOperator op) {
return args -> { return args -> {
if (args.length != 2) throw new RuntimeException("Two args expected"); if (args.length != 2) throw new ArgumentsMismatchException("Two args expected");
return doubleToNumber.apply(op.applyAsDouble(args[0].asNumber(), args[1].asNumber())); return doubleToNumber.apply(op.applyAsDouble(args[0].asNumber(), args[1].asNumber()));
}; };
} }

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser; package com.annimon.ownlang.parser;
import com.annimon.ownlang.exceptions.LexerException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser; package com.annimon.ownlang.parser;
import com.annimon.ownlang.exceptions.ParseException;
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.UserDefinedFunction; import com.annimon.ownlang.lib.UserDefinedFunction;

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.List; import java.util.List;
@ -56,14 +57,14 @@ public final class ArrayAccessExpression implements Expression {
private ArrayValue consumeArray(Value value) { private ArrayValue consumeArray(Value value) {
if (value.type() != Types.ARRAY) { if (value.type() != Types.ARRAY) {
throw new RuntimeException("Array expected"); throw new TypeException("Array expected");
} }
return (ArrayValue) value; return (ArrayValue) value;
} }
public MapValue consumeMap(Value value) { public MapValue consumeMap(Value value) {
if (value.type() != Types.MAP) { if (value.type() != Types.MAP) {
throw new RuntimeException("Map expected"); throw new TypeException("Map expected");
} }
return (MapValue) value; return (MapValue) value;
} }

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.OperationIsNotSupportedException;
import com.annimon.ownlang.exceptions.TypeException;
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;
@ -85,7 +87,7 @@ public final class BinaryExpression implements Expression {
switch (operation) { switch (operation) {
case LSHIFT: case LSHIFT:
if (value2.type() != Types.ARRAY) if (value2.type() != Types.ARRAY)
throw new RuntimeException("Cannot merge non array value to array"); throw new TypeException("Cannot merge non array value to array");
return ArrayValue.merge(value1, (ArrayValue) value2); return ArrayValue.merge(value1, (ArrayValue) value2);
case PUSH: case PUSH:
default: default:
@ -113,7 +115,7 @@ public final class BinaryExpression implements Expression {
case URSHIFT: result = (int)number1 >>> (int)number2; break; case URSHIFT: result = (int)number1 >>> (int)number2; break;
default: default:
throw new RuntimeException("Operation " + operation + " is not supported"); throw new OperationIsNotSupportedException(operation);
} }
return new NumberValue(result); return new NumberValue(result);
} }

View File

@ -1,7 +1,7 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.OperationIsNotSupportedException;
import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.StringValue;
import com.annimon.ownlang.lib.Types; import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
@ -76,7 +76,7 @@ public final class ConditionalExpression implements Expression {
case GTEQ: result = number1 >= number2; break; case GTEQ: result = number1 >= number2; break;
default: default:
throw new RuntimeException("Operation " + operation + " is not supported"); throw new OperationIsNotSupportedException(operation);
} }
return NumberValue.fromBoolean(result); return NumberValue.fromBoolean(result);
} }

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.PatternMatchingException;
import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables; import com.annimon.ownlang.lib.Variables;
@ -48,7 +49,7 @@ public final class MatchExpression implements Expression {
} }
} }
} }
throw new RuntimeException("No pattern were matched"); throw new PatternMatchingException("No pattern were matched");
} }
private boolean match(Value value, Value constant) { private boolean match(Value value, Value constant) {

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.OperationIsNotSupportedException;
import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
@ -44,7 +45,7 @@ public final class UnaryExpression implements Expression {
case COMPLEMENT: return new NumberValue(~(int)value.asNumber()); case COMPLEMENT: return new NumberValue(~(int)value.asNumber());
case NOT: return new NumberValue(value.asNumber() != 0 ? 0 : 1); case NOT: return new NumberValue(value.asNumber() != 0 ? 0 : 1);
default: default:
throw new RuntimeException("Operation " + operation + " is not supported"); throw new OperationIsNotSupportedException(operation);
} }
} }

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.VariableDoesNotExistsException;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables; import com.annimon.ownlang.lib.Variables;
@ -17,7 +18,7 @@ public final class VariableExpression implements Expression {
@Override @Override
public Value eval() { public Value eval() {
if (!Variables.isExists(name)) throw new RuntimeException("Variable does not exists: " + name); if (!Variables.isExists(name)) throw new VariableDoesNotExistsException(name);
return Variables.get(name); return Variables.get(name);
} }