Skip to content

Commit c951e67

Browse files
committed
Update script data type implementations
1 parent a1c4b3a commit c951e67

25 files changed

+187
-141
lines changed

src/main/java/com/relogiclabs/jschema/internal/script/GArray.java

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.relogiclabs.jschema.internal.script;
22

33
import com.relogiclabs.jschema.exception.ScriptCommonException;
4+
import com.relogiclabs.jschema.exception.UpdateNotSupportedException;
45
import com.relogiclabs.jschema.type.EArray;
56
import com.relogiclabs.jschema.type.EValue;
67
import lombok.EqualsAndHashCode;
@@ -10,9 +11,10 @@
1011
import java.util.Collection;
1112
import java.util.List;
1213

13-
import static com.relogiclabs.jschema.internal.util.StringHelper.concat;
1414
import static com.relogiclabs.jschema.internal.util.StringHelper.joinWith;
15-
import static com.relogiclabs.jschema.message.ErrorCode.INDX01;
15+
import static com.relogiclabs.jschema.message.ErrorCode.AUPD03;
16+
import static com.relogiclabs.jschema.message.ErrorCode.AWRT01;
17+
import static com.relogiclabs.jschema.message.ErrorCode.AWRT02;
1618

1719
@Getter
1820
@EqualsAndHashCode
@@ -26,12 +28,12 @@ private GArray(int size) {
2628

2729
public GArray(Collection<? extends EValue> collection) {
2830
this.elements = new ArrayList<>(collection.size());
29-
for(var v : collection) elements.add(new GReference(v));
31+
for(var v : collection) elements.add(new GLeftValue(v));
3032
}
3133

3234
public static GArray filledFrom(EValue value, int size) {
3335
var array = new GArray(size);
34-
for(int i = 0; i < size; i++) array.elements.add(new GReference(value));
36+
for(int i = 0; i < size; i++) array.elements.add(new GLeftValue(value));
3537
return array;
3638
}
3739

@@ -43,14 +45,22 @@ public static GArray from(EArray array, GRange range) {
4345

4446
@Override
4547
public EValue get(int index) {
48+
return elements.get(index);
49+
}
50+
51+
@Override
52+
public void set(int index, EValue value) {
4653
var size = elements.size();
47-
if(index < size) return elements.get(index);
48-
if(index > MAX_LIMIT) throw new ScriptCommonException(INDX01,
49-
concat("Array index ", index, " exceeds maximum size limit"));
50-
if(index > size) throw new ArrayIndexOutOfBoundsException(index);
51-
var reference = new GReference(VOID);
52-
elements.add(reference);
53-
return reference;
54+
if(index > MAX_LIMIT) throw new ScriptCommonException(AWRT02,
55+
"Array index " + index + " exceeds maximum size limit");
56+
if(index == size) elements.add(new GLeftValue(value));
57+
else if(index < size) {
58+
if(!(elements.get(index) instanceof GLeftValue l))
59+
throw new UpdateNotSupportedException(AUPD03,
60+
"Readonly array index " + index + " cannot be updated");
61+
l.setValue(value);
62+
} else throw new ScriptCommonException(AWRT01,
63+
"Index " + index + " is out of bounds for writing to array length " + size);
5464
}
5565

5666
@Override

src/main/java/com/relogiclabs/jschema/internal/script/GBoolean.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ public final class GBoolean implements EBoolean {
1414

1515
private final boolean value;
1616

17-
public static GBoolean of(boolean value) {
18-
return value? TRUE : FALSE;
19-
}
20-
2117
@Override
2218
public boolean getValue() {
2319
return value;
2420
}
21+
22+
@Override
23+
public String toString() {
24+
return String.valueOf(value);
25+
}
2526
}

src/main/java/com/relogiclabs/jschema/internal/script/GControl.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public EValue toIteration() {
3131
return flag == BREAK_FLAG ? VOID : this;
3232
}
3333

34-
public EValue toFunction() {
35-
return value;
34+
@Override
35+
public String toString() {
36+
return value.toString();
3637
}
3738
}

src/main/java/com/relogiclabs/jschema/internal/script/GDouble.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
@Getter
99
@EqualsAndHashCode
10-
@RequiredArgsConstructor(staticName = "of")
10+
@RequiredArgsConstructor(staticName = "from")
1111
public final class GDouble implements EDouble {
1212
private final double value;
1313

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.relogiclabs.jschema.internal.script;
22

33
import com.relogiclabs.jschema.internal.engine.Evaluator;
4-
import com.relogiclabs.jschema.internal.engine.ScopeContext;
4+
import com.relogiclabs.jschema.internal.engine.ScriptScope;
55
import com.relogiclabs.jschema.type.EValue;
66
import lombok.Getter;
77
import lombok.RequiredArgsConstructor;
@@ -11,13 +11,12 @@
1111
import static com.relogiclabs.jschema.internal.engine.ScriptTreeHelper.areCompatible;
1212
import static com.relogiclabs.jschema.internal.script.RFunction.hasVariadic;
1313
import static com.relogiclabs.jschema.internal.util.CollectionHelper.subList;
14-
import static com.relogiclabs.jschema.internal.util.MiscellaneousHelper.hasFlag;
15-
import static com.relogiclabs.jschema.message.ErrorCode.FUNS05;
14+
import static com.relogiclabs.jschema.internal.util.CommonHelper.hasFlag;
15+
import static com.relogiclabs.jschema.message.ErrorCode.FNVK02;
1616

1717
@Getter
1818
@RequiredArgsConstructor
1919
public final class GFunction implements RFunction {
20-
public static final String CONSTRAINT_PREFIX = "@";
2120
public static final int CONSTRAINT_MODE = 1;
2221
public static final int FUTURE_MODE = 3;
2322
public static final int SUBROUTINE_MODE = 4;
@@ -35,33 +34,35 @@ public GFunction(GParameter[] parameters, Evaluator body, int mode) {
3534
}
3635

3736
@Override
38-
public EValue invoke(ScopeContext functionScope, List<EValue> arguments) {
37+
public ScriptScope bind(ScriptScope parentScope, List<EValue> arguments) {
38+
areCompatible(parameters, arguments, FNVK02);
39+
var scope = new ScriptScope(parentScope);
40+
var i = 0;
41+
for(var p : parameters) scope.addVariable(p.getName(), p.isVariadic()
42+
? new GArray(subList(arguments, i)) : arguments.get(i++));
43+
return scope;
44+
}
45+
46+
@Override
47+
public EValue invoke(ScriptScope functionScope, List<EValue> arguments) {
3948
return invoke(functionScope);
4049
}
4150

42-
public EValue invoke(ScopeContext functionScope) {
51+
public EValue invoke(ScriptScope functionScope) {
4352
var result = getBody().evaluate(functionScope);
4453
if(result instanceof GControl ctrl) return ctrl.getValue();
4554
return VOID;
4655
}
4756

48-
@Override
49-
public ScopeContext bind(ScopeContext parentScope, List<EValue> arguments) {
50-
areCompatible(parameters, arguments, FUNS05);
51-
var scope = new ScopeContext(parentScope);
52-
var i = 0;
53-
for(var p : parameters) {
54-
if(p.isVariadic()) scope.addVariable(p.getName(), new GArray(subList(arguments, i)));
55-
else scope.addVariable(p.getName(), arguments.get(i++));
56-
}
57-
return scope;
57+
public boolean isConstraint() {
58+
return hasFlag(mode, CONSTRAINT_MODE);
5859
}
5960

6061
public boolean isFuture() {
6162
return hasFlag(mode, FUTURE_MODE);
6263
}
6364

64-
public static boolean isConstraint(int mode) {
65-
return hasFlag(mode, CONSTRAINT_MODE);
65+
public boolean isSubroutine() {
66+
return hasFlag(mode, SUBROUTINE_MODE);
6667
}
6768
}

src/main/java/com/relogiclabs/jschema/internal/script/GInteger.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public final class GInteger implements EInteger {
1616
private static final GInteger[] CACHE = createCache();
1717
private final long value;
1818

19-
public static GInteger of(long value) {
19+
public static GInteger from(long value) {
2020
if(value >= CACHE_START && value <= CACHE_END)
2121
return CACHE[(int) value - CACHE_START];
2222
return new GInteger(value);

src/main/java/com/relogiclabs/jschema/internal/script/GIterator.java

+12-56
Original file line numberDiff line numberDiff line change
@@ -10,78 +10,34 @@
1010

1111
import java.util.Iterator;
1212

13-
import static com.relogiclabs.jschema.internal.engine.ScriptTreeHelper.dereference;
14-
import static com.relogiclabs.jschema.internal.util.StringHelper.concat;
1513
import static com.relogiclabs.jschema.message.ErrorCode.ITER01;
16-
import static lombok.AccessLevel.PRIVATE;
1714

1815
@Getter
19-
@RequiredArgsConstructor(access = PRIVATE)
16+
@RequiredArgsConstructor
2017
public final class GIterator implements Iterable<EValue> {
2118
private final EValue iterable;
2219

23-
public static GIterator of(EValue iterable) {
24-
return new GIterator(dereference(iterable));
25-
}
26-
2720
@Override
2821
public Iterator<EValue> iterator() {
2922
if(iterable instanceof EArray array) return iterator(array);
3023
if(iterable instanceof EObject object) return iterator(object);
3124
if(iterable instanceof EString string) return iterator(string);
32-
else throw new ScriptCommonException(ITER01,
33-
concat("Invalid type ", iterable.getType(), " for iteration"));
25+
throw new ScriptCommonException(ITER01, "Invalid type "
26+
+ iterable.getType() + " for iteration");
3427
}
3528

36-
public Iterator<EValue> iterator(EArray array) {
37-
while(array.size() == 1) {
38-
if(array.get(0) instanceof EArray)
39-
array = (EArray) array.get(0);
40-
else break;
41-
}
42-
var iterator = array.elements().iterator();
43-
return new Iterator<>() {
44-
@Override
45-
public boolean hasNext() {
46-
return iterator.hasNext();
47-
}
48-
49-
@Override
50-
public EValue next() {
51-
return iterator.next();
52-
}
53-
};
29+
@SuppressWarnings("unchecked")
30+
private Iterator<EValue> iterator(EArray array) {
31+
return (Iterator<EValue>) array.elements().iterator();
5432
}
5533

56-
public Iterator<EValue> iterator(EString string) {
57-
String value = string.getValue();
58-
return new Iterator<>() {
59-
private int index = 0;
60-
61-
@Override
62-
public boolean hasNext() {
63-
return index < value.length();
64-
}
65-
66-
@Override
67-
public EValue next() {
68-
return GString.of(value.charAt(index++));
69-
}
70-
};
34+
private Iterator<EValue> iterator(EString string) {
35+
return string.getValue().codePoints().mapToObj(c
36+
-> (EValue) GString.from(c)).iterator();
7137
}
7238

73-
public Iterator<EValue> iterator(EObject object) {
74-
var iterator = object.keySet().iterator();
75-
return new Iterator<>() {
76-
@Override
77-
public boolean hasNext() {
78-
return iterator.hasNext();
79-
}
80-
81-
@Override
82-
public EValue next() {
83-
return GString.of(iterator.next());
84-
}
85-
};
39+
private Iterator<EValue> iterator(EObject object) {
40+
return object.keySet().stream().map(k
41+
-> (EValue) GString.from(k)).iterator();
8642
}
8743
}

src/main/java/com/relogiclabs/jschema/internal/script/GReference.java renamed to src/main/java/com/relogiclabs/jschema/internal/script/GLeftValue.java

+6-11
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,28 @@
22

33
import com.relogiclabs.jschema.type.EType;
44
import com.relogiclabs.jschema.type.EValue;
5+
import lombok.AllArgsConstructor;
56
import lombok.Getter;
7+
import lombok.Setter;
68

79
import java.util.Objects;
810

911
import static com.relogiclabs.jschema.internal.engine.ScriptTreeHelper.dereference;
1012

1113
@Getter
12-
public final class GReference implements EValue {
14+
@Setter
15+
@AllArgsConstructor
16+
public final class GLeftValue implements EValue {
1317
private EValue value;
1418

15-
public GReference(EValue value) {
16-
this.value = dereference(value);
17-
}
18-
19-
public void setValue(EValue value) {
20-
this.value = dereference(value);
21-
}
22-
2319
@Override
2420
public EType getType() {
2521
return value.getType();
2622
}
2723

2824
@Override
2925
public boolean equals(Object o) {
30-
if(!(o instanceof EValue v)) return false;
31-
return Objects.equals(value, dereference(v));
26+
return o instanceof EValue v && Objects.equals(value, dereference(v));
3227
}
3328

3429
@Override

src/main/java/com/relogiclabs/jschema/internal/script/GObject.java

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.relogiclabs.jschema.internal.script;
22

3+
import com.relogiclabs.jschema.exception.UpdateNotSupportedException;
34
import com.relogiclabs.jschema.type.EObject;
45
import com.relogiclabs.jschema.type.EValue;
56
import lombok.EqualsAndHashCode;
@@ -12,6 +13,7 @@
1213

1314
import static com.relogiclabs.jschema.internal.util.StringHelper.joinWith;
1415
import static com.relogiclabs.jschema.internal.util.StringHelper.quote;
16+
import static com.relogiclabs.jschema.message.ErrorCode.OUPD02;
1517

1618
@Getter
1719
@EqualsAndHashCode
@@ -24,23 +26,33 @@ public GObject(int capacity) {
2426

2527
public GObject(EObject value) {
2628
this(value.size());
27-
for(var e : value.keySet()) properties.put(e, new GReference(value.get(e)));
29+
for(var k : value.keySet()) properties.put(k, new GLeftValue(value.get(k)));
2830
}
2931

3032
public GObject(List<String> keys, List<EValue> values) {
3133
this(keys.size());
3234
for(int i = 0; i < keys.size(); i++)
33-
properties.put(keys.get(i), new GReference(values.get(i)));
35+
properties.put(keys.get(i), new GLeftValue(values.get(i)));
3436
}
3537

3638
@Override
3739
public EValue get(String key) {
38-
var value = properties.get(key);
39-
if(value == null) properties.put(key, value = new GReference(VOID));
40-
return value;
40+
return properties.get(key);
4141
}
4242

43+
@Override
4344
public void set(String key, EValue value) {
45+
var oldValue = properties.get(key);
46+
if(oldValue == null) {
47+
properties.put(key, new GLeftValue(value));
48+
return;
49+
}
50+
if(!(oldValue instanceof GLeftValue l)) throw new UpdateNotSupportedException(OUPD02,
51+
"Readonly object property '" + key + "' cannot be updated");
52+
l.setValue(value);
53+
}
54+
55+
public void put(String key, EValue value) {
4456
properties.put(key, value);
4557
}
4658

0 commit comments

Comments
 (0)