diff --git a/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownClassException.java b/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownClassException.java index 65b2fc1..8c2bed3 100644 --- a/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownClassException.java +++ b/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownClassException.java @@ -1,5 +1,7 @@ package com.annimon.ownlang.exceptions; +import com.annimon.ownlang.util.Range; + public final class UnknownClassException extends OwnLangRuntimeException { private final String className; @@ -9,6 +11,11 @@ public final class UnknownClassException extends OwnLangRuntimeException { this.className = name; } + public UnknownClassException(String name, Range range) { + super("Unknown class " + name, range); + this.className = name; + } + public String getClassName() { return className; } diff --git a/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownFunctionException.java b/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownFunctionException.java index 9aa2a9e..3d5328d 100644 --- a/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownFunctionException.java +++ b/ownlang-core/src/main/java/com/annimon/ownlang/exceptions/UnknownFunctionException.java @@ -1,5 +1,7 @@ package com.annimon.ownlang.exceptions; +import com.annimon.ownlang.util.Range; + public final class UnknownFunctionException extends OwnLangRuntimeException { private final String functionName; @@ -9,6 +11,11 @@ public final class UnknownFunctionException extends OwnLangRuntimeException { this.functionName = name; } + public UnknownFunctionException(String name, Range range) { + super("Unknown function " + name, range); + this.functionName = name; + } + public String getFunctionName() { return functionName; } diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Parser.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Parser.java index a9dbd62..cf63114 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Parser.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Parser.java @@ -746,7 +746,8 @@ public final class Parser { } private Expression objectCreation() { - if (match(TokenType.NEW)) { + if (match(TokenType.NEW)) { + final var startTokenIndex = index - 1; final String className = consume(TokenType.WORD).text(); final List args = new ArrayList<>(); consume(TokenType.LPAREN); @@ -754,7 +755,9 @@ public final class Parser { args.add(expression()); match(TokenType.COMMA); } - return new ObjectCreationExpression(className, args); + final var expr = new ObjectCreationExpression(className, args); + expr.setRange(getRange(startTokenIndex, index - 1)); + return expr; } return unary(); diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/FunctionalExpression.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/FunctionalExpression.java index f64734f..733a22b 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/FunctionalExpression.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/FunctionalExpression.java @@ -75,7 +75,7 @@ public final class FunctionalExpression extends InterruptableNode return ((FunctionValue)variable).getValue(); } } - throw new UnknownFunctionException(key); + throw new UnknownFunctionException(key, getRange()); } @Override diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/ObjectCreationExpression.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/ObjectCreationExpression.java index 1f5ec25..03476e1 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/ObjectCreationExpression.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/ObjectCreationExpression.java @@ -2,18 +2,30 @@ package com.annimon.ownlang.parser.ast; import com.annimon.ownlang.exceptions.UnknownClassException; import com.annimon.ownlang.lib.*; +import com.annimon.ownlang.util.Range; +import com.annimon.ownlang.util.SourceLocation; import java.util.Iterator; import java.util.List; -public final class ObjectCreationExpression implements Expression { +public final class ObjectCreationExpression implements Expression, SourceLocation { public final String className; public final List constructorArguments; + private Range range; public ObjectCreationExpression(String className, List constructorArguments) { this.className = className; this.constructorArguments = constructorArguments; } + + public void setRange(Range range) { + this.range = range; + } + + @Override + public Range getRange() { + return range; + } @Override public Value eval() { @@ -26,7 +38,7 @@ public final class ObjectCreationExpression implements Expression { return instantiable.newInstance(ctorArgs()); } } - throw new UnknownClassException(className); + throw new UnknownClassException(className, getRange()); } // Create an instance and put evaluated fields with method declarations