Skip to content

Commit cea99d4

Browse files
committed
Добавлен тип данных Map
1 parent 08847a5 commit cea99d4

13 files changed

+231
-6
lines changed

program.own

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,10 @@ for i = 0, i < 4, i = i + 1 {
8181
print functions[i]
8282
print "\n"
8383
print function(functions[i], 6, 3)
84-
}
84+
}
85+
86+
// map
87+
map = {"+" : add, "-" : sub. "*" : mul, "/" : div}
88+
//print map["+"]
89+
print "\n"
90+
print function(map["+"], 4, 5)

src/com/annimon/ownlang/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
public final class Main {
1919

2020
public static void main(String[] args) throws IOException {
21-
final String file = "examples/game/agar.own";
21+
final String file = "program.own";
2222
final String input = new String( Files.readAllBytes(Paths.get(file)), "UTF-8");
2323
final List<Token> tokens = new Lexer(input).tokenize();
2424
for (int i = 0; i < tokens.size(); i++) {

src/com/annimon/ownlang/lib/ArrayValue.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ public String asString() {
4141
return Arrays.toString(elements);
4242
}
4343

44+
@Override
45+
public int hashCode() {
46+
int hash = 5;
47+
hash = 79 * hash + Arrays.deepHashCode(this.elements);
48+
return hash;
49+
}
50+
51+
@Override
52+
public boolean equals(Object obj) {
53+
if (this == obj) return true;
54+
if (obj == null) return false;
55+
if (getClass() != obj.getClass())
56+
return false;
57+
final ArrayValue other = (ArrayValue) obj;
58+
return Arrays.deepEquals(this.elements, other.elements);
59+
}
60+
61+
62+
4463
@Override
4564
public String toString() {
4665
return asString();

src/com/annimon/ownlang/lib/FunctionValue.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.annimon.ownlang.lib;
22

3+
import java.util.Objects;
4+
35
/**
46
*
57
* @author aNNiMON
@@ -26,6 +28,23 @@ public Function getValue() {
2628
return value;
2729
}
2830

31+
@Override
32+
public int hashCode() {
33+
int hash = 7;
34+
hash = 71 * hash + Objects.hashCode(this.value);
35+
return hash;
36+
}
37+
38+
@Override
39+
public boolean equals(Object obj) {
40+
if (this == obj) return true;
41+
if (obj == null) return false;
42+
if (getClass() != obj.getClass())
43+
return false;
44+
final FunctionValue other = (FunctionValue) obj;
45+
return Objects.equals(this.value, other.value);
46+
}
47+
2948
@Override
3049
public String toString() {
3150
return asString();
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.annimon.ownlang.lib;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Objects;
6+
7+
/**
8+
*
9+
* @author aNNiMON
10+
*/
11+
public final class MapValue implements Value {
12+
13+
private final Map<Value, Value> map;
14+
15+
public MapValue(int size) {
16+
this.map = new HashMap<>(size);
17+
}
18+
19+
public Value get(Value key) {
20+
return map.get(key);
21+
}
22+
23+
public void set(Value key, Value value) {
24+
map.put(key, value);
25+
}
26+
27+
@Override
28+
public double asNumber() {
29+
throw new RuntimeException("Cannot cast map to number");
30+
}
31+
32+
@Override
33+
public String asString() {
34+
return map.toString();
35+
}
36+
37+
@Override
38+
public int hashCode() {
39+
int hash = 5;
40+
hash = 37 * hash + Objects.hashCode(this.map);
41+
return hash;
42+
}
43+
44+
@Override
45+
public boolean equals(Object obj) {
46+
if (this == obj) return true;
47+
if (obj == null) return false;
48+
if (getClass() != obj.getClass())
49+
return false;
50+
final MapValue other = (MapValue) obj;
51+
return Objects.equals(this.map, other.map);
52+
}
53+
54+
55+
56+
@Override
57+
public String toString() {
58+
return asString();
59+
}
60+
}

src/com/annimon/ownlang/lib/NumberValue.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ public String asString() {
2929
return Double.toString(value);
3030
}
3131

32+
@Override
33+
public int hashCode() {
34+
int hash = 3;
35+
hash = 71 * hash + (int) (Double.doubleToLongBits(this.value) ^ (Double.doubleToLongBits(this.value) >>> 32));
36+
return hash;
37+
}
38+
39+
@Override
40+
public boolean equals(Object obj) {
41+
if (this == obj) return true;
42+
if (obj == null) return false;
43+
if (getClass() != obj.getClass())
44+
return false;
45+
final NumberValue other = (NumberValue) obj;
46+
return Double.doubleToLongBits(this.value) == Double.doubleToLongBits(other.value);
47+
}
48+
49+
50+
3251
@Override
3352
public String toString() {
3453
return asString();

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.annimon.ownlang.lib;
22

3+
import java.util.Objects;
4+
35
/**
46
*
57
* @author aNNiMON
@@ -26,6 +28,23 @@ public String asString() {
2628
return value;
2729
}
2830

31+
@Override
32+
public int hashCode() {
33+
int hash = 3;
34+
hash = 97 * hash + Objects.hashCode(this.value);
35+
return hash;
36+
}
37+
38+
@Override
39+
public boolean equals(Object obj) {
40+
if (this == obj) return true;
41+
if (obj == null) return false;
42+
if (getClass() != obj.getClass())
43+
return false;
44+
final StringValue other = (StringValue) obj;
45+
return Objects.equals(this.value, other.value);
46+
}
47+
2948
@Override
3049
public String toString() {
3150
return asString();

src/com/annimon/ownlang/lib/UserDefinedFunction.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,9 @@ public Value execute(Value... args) {
3636
return rt.getResult();
3737
}
3838
}
39+
40+
@Override
41+
public String toString() {
42+
return String.format("function %s %s", argNames.toString(), body.toString());
43+
}
3944
}

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import com.annimon.ownlang.lib.UserDefinedFunction;
44
import com.annimon.ownlang.parser.ast.*;
55
import java.util.ArrayList;
6+
import java.util.HashMap;
67
import java.util.List;
8+
import java.util.Map;
79

810
/**
911
*
@@ -170,6 +172,19 @@ private Expression array() {
170172
return new ArrayExpression(elements);
171173
}
172174

175+
private Expression map() {
176+
consume(TokenType.LBRACE);
177+
final Map<Expression, Expression> elements = new HashMap<>();
178+
while (!match(TokenType.RBRACE)) {
179+
final Expression key = primary();
180+
consume(TokenType.COLON);
181+
final Expression value = expression();
182+
elements.put(key, value);
183+
match(TokenType.COMMA);
184+
}
185+
return new MapExpression(elements);
186+
}
187+
173188
private ArrayAccessExpression element() {
174189
final String variable = consume(TokenType.WORD).getText();
175190
final List<Expression> indices = new ArrayList<>();
@@ -393,15 +408,18 @@ private Expression primary() {
393408
if (match(TokenType.HEX_NUMBER)) {
394409
return new ValueExpression(Long.parseLong(current.getText(), 16));
395410
}
396-
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
397-
return function();
398-
}
399411
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LBRACKET)) {
400412
return element();
401413
}
414+
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
415+
return function();
416+
}
402417
if (lookMatch(0, TokenType.LBRACKET)) {
403418
return array();
404419
}
420+
if (lookMatch(0, TokenType.LBRACE)) {
421+
return map();
422+
}
405423
if (match(TokenType.WORD)) {
406424
return new VariableExpression(current.getText());
407425
}

src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java

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

33
import com.annimon.ownlang.lib.ArrayValue;
4+
import com.annimon.ownlang.lib.MapValue;
45
import com.annimon.ownlang.lib.Value;
56
import com.annimon.ownlang.lib.Variables;
67
import java.util.List;
@@ -21,7 +22,11 @@ public ArrayAccessExpression(String variable, List<Expression> indices) {
2122

2223
@Override
2324
public Value eval() {
24-
return getArray().get(lastIndex());
25+
Value container = Variables.get(variable);
26+
if (container instanceof ArrayValue) {
27+
return getArray().get(lastIndex());
28+
}
29+
return consumeMap(container).get(indices.get(0).eval());
2530
}
2631

2732
public ArrayValue getArray() {
@@ -49,6 +54,14 @@ private ArrayValue consumeArray(Value value) {
4954
}
5055
}
5156

57+
private MapValue consumeMap(Value value) {
58+
if (value instanceof MapValue) {
59+
return (MapValue) value;
60+
} else {
61+
throw new RuntimeException("Map expected");
62+
}
63+
}
64+
5265
@Override
5366
public void accept(Visitor visitor) {
5467
visitor.visit(this);

0 commit comments

Comments
 (0)