Skip to content

Commit 0bbbecc

Browse files
committed
Поддержка внутренних полей и функций у строк
1 parent dbdc56f commit 0bbbecc

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.annimon.ownlang.exceptions;
2+
3+
public final class UnknownPropertyException extends RuntimeException {
4+
5+
private final String propertyName;
6+
7+
public UnknownPropertyException(String name) {
8+
super("Unknown property " + name);
9+
this.propertyName = name;
10+
}
11+
12+
public String getPropertyName() {
13+
return propertyName;
14+
}
15+
}

src/main/java/com/annimon/ownlang/lib/StringValue.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.annimon.ownlang.lib;
22

3+
import com.annimon.ownlang.exceptions.UnknownPropertyException;
34
import java.util.Objects;
45

56
/**
@@ -15,6 +16,19 @@ public final class StringValue implements Value {
1516
public StringValue(String value) {
1617
this.value = value;
1718
}
19+
20+
public Value access(Value property) {
21+
switch (property.asString()) {
22+
// Properties
23+
case "length":
24+
return NumberValue.of(length());
25+
26+
// Functions
27+
case "trim":
28+
return new FunctionValue(args -> new StringValue(value.trim()));
29+
}
30+
throw new UnknownPropertyException(property.asString());
31+
}
1832

1933
public int length() {
2034
return value.length();
@@ -82,5 +96,4 @@ public int compareTo(Value o) {
8296
public String toString() {
8397
return asString();
8498
}
85-
8699
}

src/main/java/com/annimon/ownlang/parser/Parser.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,23 @@ private Expression value() {
782782
return new ValueExpression(createNumber(current.getText(), 16));
783783
}
784784
if (match(TokenType.TEXT)) {
785-
return new ValueExpression(current.getText());
785+
final ValueExpression strExpr = new ValueExpression(current.getText());
786+
// "text".property || "text".func()
787+
if (lookMatch(0, TokenType.DOT)) {
788+
if (lookMatch(1, TokenType.WORD) && lookMatch(2, TokenType.LPAREN)) {
789+
match(TokenType.DOT);
790+
return functionChain(new ContainerAccessExpression(
791+
strExpr, Collections.singletonList(
792+
new ValueExpression(consume(TokenType.WORD).getText())
793+
)));
794+
}
795+
final List<Expression> indices = variableSuffix();
796+
if (indices.isEmpty()) {
797+
return strExpr;
798+
}
799+
return new ContainerAccessExpression(strExpr, indices);
800+
}
801+
return strExpr;
786802
}
787803
throw new ParseException("Unknown expression: " + current);
788804
}

src/main/java/com/annimon/ownlang/parser/ast/ContainerAccessExpression.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public Value get() {
4848

4949
case Types.MAP:
5050
return ((MapValue) container).get(lastIndex);
51+
52+
case Types.STRING:
53+
return ((StringValue) container).access(lastIndex);
5154

5255
default:
5356
throw new TypeException("Array or map expected. Got " + Types.typeToString(container.type()));
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def testLength() {
2+
assertEquals(3, "123".length)
3+
s = "test"
4+
assertEquals(4, s.length)
5+
}
6+
7+
def testTrim() {
8+
s = " test "
9+
assertEquals("test", s.trim())
10+
}

0 commit comments

Comments
 (0)