From b194a7b9b9bb4790ede5e47a02c1a99b313dbe50 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 19 Jan 2016 13:38:56 +0200 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArgumentsMismatchException.java | 11 ++++ .../LexerException.java | 2 +- .../OperationIsNotSupportedException.java | 8 +++ .../ParseException.java | 2 +- .../exceptions/PatternMatchingException.java | 11 ++++ .../ownlang/exceptions/TypeException.java | 8 +++ .../exceptions/UnknownFunctionException.java | 15 +++++ .../VariableDoesNotExistsException.java | 15 +++++ src/com/annimon/ownlang/lib/ArrayValue.java | 3 +- .../annimon/ownlang/lib/FunctionValue.java | 3 +- src/com/annimon/ownlang/lib/Functions.java | 3 +- src/com/annimon/ownlang/lib/MapValue.java | 3 +- .../ownlang/lib/UserDefinedFunction.java | 3 +- .../annimon/ownlang/lib/modules/canvas.java | 5 +- .../modules/functions/functional_combine.java | 55 +++++++++++++++++++ .../modules/functions/functional_filter.java | 8 ++- .../modules/functions/functional_foreach.java | 8 ++- .../lib/modules/functions/functional_map.java | 12 ++-- .../modules/functions/functional_reduce.java | 8 ++- .../lib/modules/functions/http_http.java | 10 ++-- .../lib/modules/functions/http_urlencode.java | 3 +- .../lib/modules/functions/json_decode.java | 3 +- .../lib/modules/functions/json_encode.java | 3 +- .../lib/modules/functions/std_foreach.java | 8 ++- .../lib/modules/functions/std_length.java | 3 +- .../lib/modules/functions/std_sleep.java | 13 +++-- .../lib/modules/functions/std_thread.java | 10 +--- src/com/annimon/ownlang/lib/modules/math.java | 5 +- src/com/annimon/ownlang/parser/Lexer.java | 1 + src/com/annimon/ownlang/parser/Parser.java | 1 + .../parser/ast/ArrayAccessExpression.java | 5 +- .../ownlang/parser/ast/BinaryExpression.java | 6 +- .../parser/ast/ConditionalExpression.java | 4 +- .../ownlang/parser/ast/MatchExpression.java | 3 +- .../ownlang/parser/ast/UnaryExpression.java | 3 +- .../parser/ast/VariableExpression.java | 3 +- 36 files changed, 209 insertions(+), 58 deletions(-) create mode 100644 src/com/annimon/ownlang/exceptions/ArgumentsMismatchException.java rename src/com/annimon/ownlang/{parser => exceptions}/LexerException.java (87%) create mode 100644 src/com/annimon/ownlang/exceptions/OperationIsNotSupportedException.java rename src/com/annimon/ownlang/{parser => exceptions}/ParseException.java (84%) create mode 100644 src/com/annimon/ownlang/exceptions/PatternMatchingException.java create mode 100644 src/com/annimon/ownlang/exceptions/TypeException.java create mode 100644 src/com/annimon/ownlang/exceptions/UnknownFunctionException.java create mode 100644 src/com/annimon/ownlang/exceptions/VariableDoesNotExistsException.java create mode 100644 src/com/annimon/ownlang/lib/modules/functions/functional_combine.java diff --git a/src/com/annimon/ownlang/exceptions/ArgumentsMismatchException.java b/src/com/annimon/ownlang/exceptions/ArgumentsMismatchException.java new file mode 100644 index 0000000..165f863 --- /dev/null +++ b/src/com/annimon/ownlang/exceptions/ArgumentsMismatchException.java @@ -0,0 +1,11 @@ +package com.annimon.ownlang.exceptions; + +public final class ArgumentsMismatchException extends RuntimeException { + + public ArgumentsMismatchException() { + } + + public ArgumentsMismatchException(String message) { + super(message); + } +} diff --git a/src/com/annimon/ownlang/parser/LexerException.java b/src/com/annimon/ownlang/exceptions/LexerException.java similarity index 87% rename from src/com/annimon/ownlang/parser/LexerException.java rename to src/com/annimon/ownlang/exceptions/LexerException.java index caab066..26689e1 100644 --- a/src/com/annimon/ownlang/parser/LexerException.java +++ b/src/com/annimon/ownlang/exceptions/LexerException.java @@ -1,4 +1,4 @@ -package com.annimon.ownlang.parser; +package com.annimon.ownlang.exceptions; /** * diff --git a/src/com/annimon/ownlang/exceptions/OperationIsNotSupportedException.java b/src/com/annimon/ownlang/exceptions/OperationIsNotSupportedException.java new file mode 100644 index 0000000..fffabca --- /dev/null +++ b/src/com/annimon/ownlang/exceptions/OperationIsNotSupportedException.java @@ -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"); + } +} diff --git a/src/com/annimon/ownlang/parser/ParseException.java b/src/com/annimon/ownlang/exceptions/ParseException.java similarity index 84% rename from src/com/annimon/ownlang/parser/ParseException.java rename to src/com/annimon/ownlang/exceptions/ParseException.java index 40ae395..ed2d47e 100644 --- a/src/com/annimon/ownlang/parser/ParseException.java +++ b/src/com/annimon/ownlang/exceptions/ParseException.java @@ -1,4 +1,4 @@ -package com.annimon.ownlang.parser; +package com.annimon.ownlang.exceptions; /** * diff --git a/src/com/annimon/ownlang/exceptions/PatternMatchingException.java b/src/com/annimon/ownlang/exceptions/PatternMatchingException.java new file mode 100644 index 0000000..05075f8 --- /dev/null +++ b/src/com/annimon/ownlang/exceptions/PatternMatchingException.java @@ -0,0 +1,11 @@ +package com.annimon.ownlang.exceptions; + +public final class PatternMatchingException extends RuntimeException { + + public PatternMatchingException() { + } + + public PatternMatchingException(String message) { + super(message); + } +} diff --git a/src/com/annimon/ownlang/exceptions/TypeException.java b/src/com/annimon/ownlang/exceptions/TypeException.java new file mode 100644 index 0000000..c2e853b --- /dev/null +++ b/src/com/annimon/ownlang/exceptions/TypeException.java @@ -0,0 +1,8 @@ +package com.annimon.ownlang.exceptions; + +public final class TypeException extends RuntimeException { + + public TypeException(String message) { + super(message); + } +} diff --git a/src/com/annimon/ownlang/exceptions/UnknownFunctionException.java b/src/com/annimon/ownlang/exceptions/UnknownFunctionException.java new file mode 100644 index 0000000..74ad7d3 --- /dev/null +++ b/src/com/annimon/ownlang/exceptions/UnknownFunctionException.java @@ -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; + } +} diff --git a/src/com/annimon/ownlang/exceptions/VariableDoesNotExistsException.java b/src/com/annimon/ownlang/exceptions/VariableDoesNotExistsException.java new file mode 100644 index 0000000..0981de1 --- /dev/null +++ b/src/com/annimon/ownlang/exceptions/VariableDoesNotExistsException.java @@ -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; + } +} diff --git a/src/com/annimon/ownlang/lib/ArrayValue.java b/src/com/annimon/ownlang/lib/ArrayValue.java index e34b8ce..fb28e8c 100644 --- a/src/com/annimon/ownlang/lib/ArrayValue.java +++ b/src/com/annimon/ownlang/lib/ArrayValue.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.TypeException; import java.util.Arrays; import java.util.Iterator; @@ -61,7 +62,7 @@ public final class ArrayValue implements Value, Iterable { @Override public double asNumber() { - throw new RuntimeException("Cannot cast array to number"); + throw new TypeException("Cannot cast array to number"); } @Override diff --git a/src/com/annimon/ownlang/lib/FunctionValue.java b/src/com/annimon/ownlang/lib/FunctionValue.java index b2544f5..8ef1aa0 100644 --- a/src/com/annimon/ownlang/lib/FunctionValue.java +++ b/src/com/annimon/ownlang/lib/FunctionValue.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.TypeException; import java.util.Objects; /** @@ -23,7 +24,7 @@ public final class FunctionValue implements Value { @Override public double asNumber() { - throw new RuntimeException("Cannot cast function to number"); + throw new TypeException("Cannot cast function to number"); } @Override diff --git a/src/com/annimon/ownlang/lib/Functions.java b/src/com/annimon/ownlang/lib/Functions.java index 8aa188a..eda7d0c 100644 --- a/src/com/annimon/ownlang/lib/Functions.java +++ b/src/com/annimon/ownlang/lib/Functions.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.UnknownFunctionException; import java.util.HashMap; import java.util.Map; @@ -20,7 +21,7 @@ public final class Functions { } 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); } diff --git a/src/com/annimon/ownlang/lib/MapValue.java b/src/com/annimon/ownlang/lib/MapValue.java index 3eff1c7..369102d 100644 --- a/src/com/annimon/ownlang/lib/MapValue.java +++ b/src/com/annimon/ownlang/lib/MapValue.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.TypeException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -46,7 +47,7 @@ public class MapValue implements Value, Iterable> { @Override public double asNumber() { - throw new RuntimeException("Cannot cast map to number"); + throw new TypeException("Cannot cast map to number"); } @Override diff --git a/src/com/annimon/ownlang/lib/UserDefinedFunction.java b/src/com/annimon/ownlang/lib/UserDefinedFunction.java index fabe27b..0c44066 100644 --- a/src/com/annimon/ownlang/lib/UserDefinedFunction.java +++ b/src/com/annimon/ownlang/lib/UserDefinedFunction.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.parser.ast.ReturnStatement; import com.annimon.ownlang.parser.ast.Statement; import java.util.List; @@ -30,7 +31,7 @@ public final class UserDefinedFunction implements Function { @Override public Value execute(Value... values) { final int size = values.length; - if (size != getArgsCount()) throw new RuntimeException("Args count mismatch"); + if (size != getArgsCount()) throw new ArgumentsMismatchException("Arguments count mismatch"); try { Variables.push(); diff --git a/src/com/annimon/ownlang/lib/modules/canvas.java b/src/com/annimon/ownlang/lib/modules/canvas.java index c9d0ee9..b4e05c4 100644 --- a/src/com/annimon/ownlang/lib/modules/canvas.java +++ b/src/com/annimon/ownlang/lib/modules/canvas.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib.modules; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.*; import java.awt.Color; import java.awt.Dimension; @@ -89,7 +90,7 @@ public final class canvas implements Module { private static Function intConsumer4Convert(IntConsumer4 consumer) { 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 y = (int) args[1].asNumber(); int w = (int) args[2].asNumber(); @@ -186,7 +187,7 @@ public final class canvas implements Module { @Override 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 y = (int) args[2].asNumber(); graphics.drawString(args[0].asString(), x, y); diff --git a/src/com/annimon/ownlang/lib/modules/functions/functional_combine.java b/src/com/annimon/ownlang/lib/modules/functions/functional_combine.java new file mode 100644 index 0000000..980106c --- /dev/null +++ b/src/com/annimon/ownlang/lib/modules/functions/functional_combine.java @@ -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 element : map) { + final Value newKey = keyMapper.execute(element.getKey()); + final Value newValue = valueMapper.execute(element.getValue()); + result.set(newKey, newValue); + } + return result; + } +} \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/functional_filter.java b/src/com/annimon/ownlang/lib/modules/functions/functional_filter.java index c1f7ed9..86ff481 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/functional_filter.java +++ b/src/com/annimon/ownlang/lib/modules/functions/functional_filter.java @@ -1,5 +1,7 @@ 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 java.util.ArrayList; import java.util.List; @@ -10,10 +12,10 @@ public final class functional_filter implements Function { @Override 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) { - throw new RuntimeException("Function expected in second arg"); + throw new TypeException("Function expected in second arg"); } final Value container = args[0]; final Function consumer = ((FunctionValue) args[1]).getValue(); @@ -25,7 +27,7 @@ public final class functional_filter implements Function { 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) { diff --git a/src/com/annimon/ownlang/lib/modules/functions/functional_foreach.java b/src/com/annimon/ownlang/lib/modules/functions/functional_foreach.java index bf9bf33..8bc26a0 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/functional_foreach.java +++ b/src/com/annimon/ownlang/lib/modules/functions/functional_foreach.java @@ -1,5 +1,7 @@ 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 java.util.Map; @@ -8,10 +10,10 @@ public final class functional_foreach implements Function { @Override 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) { - throw new RuntimeException("Function expected in second arg"); + throw new TypeException("Function expected in second arg"); } final Value container = args[0]; final Function consumer = ((FunctionValue) args[1]).getValue(); @@ -29,6 +31,6 @@ public final class functional_foreach implements Function { } return NumberValue.ZERO; } - throw new RuntimeException("Invalid first argument. Array or map exprected"); + throw new TypeException("Invalid first argument. Array or map exprected"); } } \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/functional_map.java b/src/com/annimon/ownlang/lib/modules/functions/functional_map.java index 980106c..2c883ac 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/functional_map.java +++ b/src/com/annimon/ownlang/lib/modules/functions/functional_map.java @@ -1,5 +1,7 @@ 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 java.util.Map; @@ -8,12 +10,12 @@ 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"); + if (args.length < 2) throw new ArgumentsMismatchException("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"); + throw new TypeException("Function expected in second arg"); } final Function mapper = ((FunctionValue) args[1]).getValue(); return mapArray((ArrayValue) container, mapper); @@ -21,17 +23,17 @@ public final class functional_map implements Function { if (container.type() == Types.MAP) { 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) { - 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 valueMapper = ((FunctionValue) args[2]).getValue(); 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) { diff --git a/src/com/annimon/ownlang/lib/modules/functions/functional_reduce.java b/src/com/annimon/ownlang/lib/modules/functions/functional_reduce.java index 7a886eb..781b3bd 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/functional_reduce.java +++ b/src/com/annimon/ownlang/lib/modules/functions/functional_reduce.java @@ -1,5 +1,7 @@ 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 java.util.Map; @@ -8,10 +10,10 @@ public final class functional_reduce implements Function { @Override 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) { - throw new RuntimeException("Function expected in third arg"); + throw new TypeException("Function expected in third arg"); } final Value container = args[0]; final Value identity = args[1]; @@ -32,6 +34,6 @@ public final class functional_reduce implements Function { } return result; } - throw new RuntimeException("Invalid first argument. Array or map exprected"); + throw new TypeException("Invalid first argument. Array or map exprected"); } } \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/http_http.java b/src/com/annimon/ownlang/lib/modules/functions/http_http.java index 50df52e..e89c61a 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/http_http.java +++ b/src/com/annimon/ownlang/lib/modules/functions/http_http.java @@ -1,5 +1,7 @@ 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 java.io.IOException; import java.io.UnsupportedEncodingException; @@ -49,7 +51,7 @@ public final class http_http implements Function { case 4: // http(url, method, params, callback) 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(); method = args[1].asString(); @@ -57,17 +59,17 @@ public final class http_http implements Function { case 5: // http(url, method, params, headerParams, callback) 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) { - throw new RuntimeException("Fifth arg must be a function callback"); + throw new TypeException("Fifth arg must be a function callback"); } url = args[0].asString(); method = args[1].asString(); return process(url, method, args[2], (MapValue) args[3], (FunctionValue) args[4]); default: - throw new RuntimeException("Wrong number of arguments"); + throw new ArgumentsMismatchException("Wrong number of arguments"); } } diff --git a/src/com/annimon/ownlang/lib/modules/functions/http_urlencode.java b/src/com/annimon/ownlang/lib/modules/functions/http_urlencode.java index 02ff8ff..39a00c9 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/http_urlencode.java +++ b/src/com/annimon/ownlang/lib/modules/functions/http_urlencode.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib.modules.functions; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.lib.StringValue; import com.annimon.ownlang.lib.Value; @@ -10,7 +11,7 @@ public final class http_urlencode implements Function { @Override 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"; if (args.length >= 2) { diff --git a/src/com/annimon/ownlang/lib/modules/functions/json_decode.java b/src/com/annimon/ownlang/lib/modules/functions/json_decode.java index 97fb9d5..57be629 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/json_decode.java +++ b/src/com/annimon/ownlang/lib/modules/functions/json_decode.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib.modules.functions; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.*; import java.util.Iterator; import org.json.*; @@ -8,7 +9,7 @@ public final class json_decode implements Function { @Override 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 { final String jsonRaw = args[0].asString(); final Object root = new JSONTokener(jsonRaw).nextValue(); diff --git a/src/com/annimon/ownlang/lib/modules/functions/json_encode.java b/src/com/annimon/ownlang/lib/modules/functions/json_encode.java index 8263ac1..23d80e8 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/json_encode.java +++ b/src/com/annimon/ownlang/lib/modules/functions/json_encode.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib.modules.functions; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.*; import java.util.Map; import org.json.*; @@ -8,7 +9,7 @@ public final class json_encode implements Function { @Override 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 { final Object root = process(args[0]); final String jsonRaw = JSONObject.valueToString(root); diff --git a/src/com/annimon/ownlang/lib/modules/functions/std_foreach.java b/src/com/annimon/ownlang/lib/modules/functions/std_foreach.java index dfb7493..d07283b 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/std_foreach.java +++ b/src/com/annimon/ownlang/lib/modules/functions/std_foreach.java @@ -1,5 +1,7 @@ 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 java.util.Map; @@ -8,9 +10,9 @@ public final class std_foreach implements Function { @Override 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 Value container = args[0]; if (container.type() == Types.ARRAY) { @@ -27,6 +29,6 @@ public final class std_foreach implements Function { } return NumberValue.ZERO; } - return NumberValue.ZERO; + throw new TypeException("First arg must be an array or map"); } } \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/std_length.java b/src/com/annimon/ownlang/lib/modules/functions/std_length.java index b6aa93d..8bdf40b 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/std_length.java +++ b/src/com/annimon/ownlang/lib/modules/functions/std_length.java @@ -1,12 +1,13 @@ package com.annimon.ownlang.lib.modules.functions; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.*; public final class std_length implements Function { @Override 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]; int length; diff --git a/src/com/annimon/ownlang/lib/modules/functions/std_sleep.java b/src/com/annimon/ownlang/lib/modules/functions/std_sleep.java index 4b25ea3..c86810d 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/std_sleep.java +++ b/src/com/annimon/ownlang/lib/modules/functions/std_sleep.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib.modules.functions; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.Value; @@ -8,12 +9,12 @@ public final class std_sleep implements Function { @Override public Value execute(Value... args) { - if (args.length == 1) { - try { - Thread.sleep((long) args[0].asNumber()); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } + if (args.length != 1) throw new ArgumentsMismatchException("One argument expected"); + + try { + Thread.sleep((long) args[0].asNumber()); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); } return NumberValue.ZERO; } diff --git a/src/com/annimon/ownlang/lib/modules/functions/std_thread.java b/src/com/annimon/ownlang/lib/modules/functions/std_thread.java index 1025e75..785fce2 100644 --- a/src/com/annimon/ownlang/lib/modules/functions/std_thread.java +++ b/src/com/annimon/ownlang/lib/modules/functions/std_thread.java @@ -1,11 +1,7 @@ package com.annimon.ownlang.lib.modules.functions; -import com.annimon.ownlang.lib.Function; -import com.annimon.ownlang.lib.FunctionValue; -import com.annimon.ownlang.lib.Functions; -import com.annimon.ownlang.lib.NumberValue; -import com.annimon.ownlang.lib.Types; -import com.annimon.ownlang.lib.Value; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; +import com.annimon.ownlang.lib.*; public final class std_thread implements Function { @@ -13,7 +9,7 @@ public final class std_thread implements Function { 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; if (args[0].type() == Types.FUNCTION) { diff --git a/src/com/annimon/ownlang/lib/modules/math.java b/src/com/annimon/ownlang/lib/modules/math.java index 270dfc4..37f08e9 100644 --- a/src/com/annimon/ownlang/lib/modules/math.java +++ b/src/com/annimon/ownlang/lib/modules/math.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib.modules; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.*; import java.util.function.DoubleBinaryOperator; import java.util.function.DoubleFunction; @@ -57,14 +58,14 @@ public final class math implements Module { private static Function functionConvert(DoubleUnaryOperator op) { 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())); }; } private static Function biFunctionConvert(DoubleBinaryOperator op) { 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())); }; } diff --git a/src/com/annimon/ownlang/parser/Lexer.java b/src/com/annimon/ownlang/parser/Lexer.java index 6046e18..fe206b6 100644 --- a/src/com/annimon/ownlang/parser/Lexer.java +++ b/src/com/annimon/ownlang/parser/Lexer.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.parser; +import com.annimon.ownlang.exceptions.LexerException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/src/com/annimon/ownlang/parser/Parser.java b/src/com/annimon/ownlang/parser/Parser.java index 1c90a13..f3c75e1 100644 --- a/src/com/annimon/ownlang/parser/Parser.java +++ b/src/com/annimon/ownlang/parser/Parser.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.parser; +import com.annimon.ownlang.exceptions.ParseException; import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.StringValue; import com.annimon.ownlang.lib.UserDefinedFunction; diff --git a/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java b/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java index e5dfff8..2474c5e 100644 --- a/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java +++ b/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.parser.ast; +import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.lib.*; import java.util.List; @@ -56,14 +57,14 @@ public final class ArrayAccessExpression implements Expression { private ArrayValue consumeArray(Value value) { if (value.type() != Types.ARRAY) { - throw new RuntimeException("Array expected"); + throw new TypeException("Array expected"); } return (ArrayValue) value; } public MapValue consumeMap(Value value) { if (value.type() != Types.MAP) { - throw new RuntimeException("Map expected"); + throw new TypeException("Map expected"); } return (MapValue) value; } diff --git a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java index 985e6b8..e870ebb 100644 --- a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java +++ b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java @@ -1,5 +1,7 @@ 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.NumberValue; import com.annimon.ownlang.lib.StringValue; @@ -85,7 +87,7 @@ public final class BinaryExpression implements Expression { switch (operation) { case LSHIFT: 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); case PUSH: default: @@ -113,7 +115,7 @@ public final class BinaryExpression implements Expression { case URSHIFT: result = (int)number1 >>> (int)number2; break; default: - throw new RuntimeException("Operation " + operation + " is not supported"); + throw new OperationIsNotSupportedException(operation); } return new NumberValue(result); } diff --git a/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java b/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java index 5e8610b..569df03 100644 --- a/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java +++ b/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java @@ -1,7 +1,7 @@ package com.annimon.ownlang.parser.ast; +import com.annimon.ownlang.exceptions.OperationIsNotSupportedException; import com.annimon.ownlang.lib.NumberValue; -import com.annimon.ownlang.lib.StringValue; import com.annimon.ownlang.lib.Types; import com.annimon.ownlang.lib.Value; @@ -76,7 +76,7 @@ public final class ConditionalExpression implements Expression { case GTEQ: result = number1 >= number2; break; default: - throw new RuntimeException("Operation " + operation + " is not supported"); + throw new OperationIsNotSupportedException(operation); } return NumberValue.fromBoolean(result); } diff --git a/src/com/annimon/ownlang/parser/ast/MatchExpression.java b/src/com/annimon/ownlang/parser/ast/MatchExpression.java index 541577a..877887d 100644 --- a/src/com/annimon/ownlang/parser/ast/MatchExpression.java +++ b/src/com/annimon/ownlang/parser/ast/MatchExpression.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.parser.ast; +import com.annimon.ownlang.exceptions.PatternMatchingException; import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.Value; 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) { diff --git a/src/com/annimon/ownlang/parser/ast/UnaryExpression.java b/src/com/annimon/ownlang/parser/ast/UnaryExpression.java index fc01659..b9abd3b 100644 --- a/src/com/annimon/ownlang/parser/ast/UnaryExpression.java +++ b/src/com/annimon/ownlang/parser/ast/UnaryExpression.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.parser.ast; +import com.annimon.ownlang.exceptions.OperationIsNotSupportedException; import com.annimon.ownlang.lib.NumberValue; 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 NOT: return new NumberValue(value.asNumber() != 0 ? 0 : 1); default: - throw new RuntimeException("Operation " + operation + " is not supported"); + throw new OperationIsNotSupportedException(operation); } } diff --git a/src/com/annimon/ownlang/parser/ast/VariableExpression.java b/src/com/annimon/ownlang/parser/ast/VariableExpression.java index 1971eea..794f3a9 100644 --- a/src/com/annimon/ownlang/parser/ast/VariableExpression.java +++ b/src/com/annimon/ownlang/parser/ast/VariableExpression.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.parser.ast; +import com.annimon.ownlang.exceptions.VariableDoesNotExistsException; import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Variables; @@ -17,7 +18,7 @@ public final class VariableExpression implements Expression { @Override 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); }