From 0bbbeccda63746d01ea04ba9651a8e0a31489adc Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 4 Jan 2019 21:59:37 +0200 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=B8=D1=85=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B9=20=D0=B8=20=D1=84?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B9=20=D1=83=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exceptions/UnknownPropertyException.java | 15 +++++++++++++++ .../com/annimon/ownlang/lib/StringValue.java | 15 ++++++++++++++- .../com/annimon/ownlang/parser/Parser.java | 18 +++++++++++++++++- .../parser/ast/ContainerAccessExpression.java | 3 +++ src/test/resources/other/stringFunctions.own | 10 ++++++++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/annimon/ownlang/exceptions/UnknownPropertyException.java create mode 100644 src/test/resources/other/stringFunctions.own diff --git a/src/main/java/com/annimon/ownlang/exceptions/UnknownPropertyException.java b/src/main/java/com/annimon/ownlang/exceptions/UnknownPropertyException.java new file mode 100644 index 0000000..4156c59 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/exceptions/UnknownPropertyException.java @@ -0,0 +1,15 @@ +package com.annimon.ownlang.exceptions; + +public final class UnknownPropertyException extends RuntimeException { + + private final String propertyName; + + public UnknownPropertyException(String name) { + super("Unknown property " + name); + this.propertyName = name; + } + + public String getPropertyName() { + return propertyName; + } +} diff --git a/src/main/java/com/annimon/ownlang/lib/StringValue.java b/src/main/java/com/annimon/ownlang/lib/StringValue.java index 8a1ac22..f665d04 100644 --- a/src/main/java/com/annimon/ownlang/lib/StringValue.java +++ b/src/main/java/com/annimon/ownlang/lib/StringValue.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.UnknownPropertyException; import java.util.Objects; /** @@ -15,6 +16,19 @@ public final class StringValue implements Value { public StringValue(String value) { this.value = value; } + + public Value access(Value property) { + switch (property.asString()) { + // Properties + case "length": + return NumberValue.of(length()); + + // Functions + case "trim": + return new FunctionValue(args -> new StringValue(value.trim())); + } + throw new UnknownPropertyException(property.asString()); + } public int length() { return value.length(); @@ -82,5 +96,4 @@ public final class StringValue implements Value { public String toString() { return asString(); } - } diff --git a/src/main/java/com/annimon/ownlang/parser/Parser.java b/src/main/java/com/annimon/ownlang/parser/Parser.java index 2f5a270..58b35ae 100644 --- a/src/main/java/com/annimon/ownlang/parser/Parser.java +++ b/src/main/java/com/annimon/ownlang/parser/Parser.java @@ -782,7 +782,23 @@ public final class Parser { return new ValueExpression(createNumber(current.getText(), 16)); } if (match(TokenType.TEXT)) { - return new ValueExpression(current.getText()); + final ValueExpression strExpr = new ValueExpression(current.getText()); + // "text".property || "text".func() + if (lookMatch(0, TokenType.DOT)) { + if (lookMatch(1, TokenType.WORD) && lookMatch(2, TokenType.LPAREN)) { + match(TokenType.DOT); + return functionChain(new ContainerAccessExpression( + strExpr, Collections.singletonList( + new ValueExpression(consume(TokenType.WORD).getText()) + ))); + } + final List indices = variableSuffix(); + if (indices.isEmpty()) { + return strExpr; + } + return new ContainerAccessExpression(strExpr, indices); + } + return strExpr; } throw new ParseException("Unknown expression: " + current); } diff --git a/src/main/java/com/annimon/ownlang/parser/ast/ContainerAccessExpression.java b/src/main/java/com/annimon/ownlang/parser/ast/ContainerAccessExpression.java index 794b842..27bb676 100644 --- a/src/main/java/com/annimon/ownlang/parser/ast/ContainerAccessExpression.java +++ b/src/main/java/com/annimon/ownlang/parser/ast/ContainerAccessExpression.java @@ -48,6 +48,9 @@ public final class ContainerAccessExpression implements Expression, Accessible { case Types.MAP: return ((MapValue) container).get(lastIndex); + + case Types.STRING: + return ((StringValue) container).access(lastIndex); default: throw new TypeException("Array or map expected. Got " + Types.typeToString(container.type())); diff --git a/src/test/resources/other/stringFunctions.own b/src/test/resources/other/stringFunctions.own new file mode 100644 index 0000000..154f768 --- /dev/null +++ b/src/test/resources/other/stringFunctions.own @@ -0,0 +1,10 @@ +def testLength() { + assertEquals(3, "123".length) + s = "test" + assertEquals(4, s.length) +} + +def testTrim() { + s = " test " + assertEquals("test", s.trim()) +} \ No newline at end of file