Skip to content

Commit 135ecf8

Browse files
committed
Добавлено больше операторов присвоения
1 parent 802927e commit 135ecf8

14 files changed

+145
-92
lines changed

program.own

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,14 @@ println funcWithOptionalArgs("+", 2)
220220
println funcWithOptionalArgs("*", 10, "<!")
221221

222222
v1 = v2 = v3 = v4 = 5
223-
echo(v1, v2, v3, v4)
223+
echo(v1, v2, v3, v4)
224+
225+
x = 5
226+
x += 10
227+
x *= 2
228+
println x
229+
230+
xarr = [0, 5, 2]
231+
xarr[0] += xarr[1]
232+
xarr[0] *= xarr[2]
233+
println xarr[0]

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ public final class Lexer {
4646
OPERATORS.put("!=", TokenType.EXCLEQ);
4747
OPERATORS.put("<=", TokenType.LTEQ);
4848
OPERATORS.put(">=", TokenType.GTEQ);
49+
50+
OPERATORS.put("+=", TokenType.PLUSEQ);
51+
OPERATORS.put("-=", TokenType.MINUSEQ);
52+
OPERATORS.put("*=", TokenType.STAREQ);
53+
OPERATORS.put("/=", TokenType.SLASHEQ);
54+
OPERATORS.put("%=", TokenType.PERCENTEQ);
55+
OPERATORS.put("&=", TokenType.AMPEQ);
56+
OPERATORS.put("^=", TokenType.CARETEQ);
57+
OPERATORS.put("|=", TokenType.BAREQ);
58+
OPERATORS.put("::=", TokenType.COLONCOLONEQ);
59+
OPERATORS.put("<<=", TokenType.LTLTEQ);
60+
OPERATORS.put(">>=", TokenType.GTGTEQ);
61+
OPERATORS.put(">>>=", TokenType.GTGTGTEQ);
4962

5063
OPERATORS.put("::", TokenType.COLONCOLON);
5164

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

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@
1717
public final class Parser {
1818

1919
private static final Token EOF = new Token(TokenType.EOF, "", -1, -1);
20+
21+
private static final Map<TokenType, BinaryExpression.Operator> assignOperator;
22+
static {
23+
assignOperator = new HashMap<>(BinaryExpression.Operator.values().length + 1);
24+
assignOperator.put(TokenType.EQ, null);
25+
assignOperator.put(TokenType.PLUSEQ, BinaryExpression.Operator.ADD);
26+
assignOperator.put(TokenType.MINUSEQ, BinaryExpression.Operator.SUBTRACT);
27+
assignOperator.put(TokenType.STAREQ, BinaryExpression.Operator.MULTIPLY);
28+
assignOperator.put(TokenType.SLASHEQ, BinaryExpression.Operator.DIVIDE);
29+
assignOperator.put(TokenType.PERCENTEQ, BinaryExpression.Operator.REMAINDER);
30+
assignOperator.put(TokenType.AMPEQ, BinaryExpression.Operator.AND);
31+
assignOperator.put(TokenType.CARETEQ, BinaryExpression.Operator.XOR);
32+
assignOperator.put(TokenType.BAREQ, BinaryExpression.Operator.OR);
33+
assignOperator.put(TokenType.COLONCOLONEQ, BinaryExpression.Operator.PUSH);
34+
assignOperator.put(TokenType.LTLTEQ, BinaryExpression.Operator.LSHIFT);
35+
assignOperator.put(TokenType.GTGTEQ, BinaryExpression.Operator.RSHIFT);
36+
assignOperator.put(TokenType.GTGTGTEQ, BinaryExpression.Operator.URSHIFT);
37+
}
2038

2139
private final List<Token> tokens;
2240
private final int size;
@@ -334,22 +352,24 @@ private Expression assignment() {
334352
}
335353

336354
private Expression assignmentStrict() {
337-
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.EQ)) {
338-
final String variable = consume(TokenType.WORD).getText();
339-
consume(TokenType.EQ);
340-
return new AssignmentExpression(variable, expression());
355+
final int position = pos;
356+
final Expression targetExpr = qualifiedName();
357+
if ((targetExpr == null) || !(targetExpr instanceof Accessible)) {
358+
pos = position;
359+
return null;
341360
}
342361

343-
final int position = pos;
344-
final Expression qualifiedNameExpr = qualifiedName();
345-
if (lookMatch(0, TokenType.EQ) && (qualifiedNameExpr instanceof ContainerAccessExpression)) {
346-
consume(TokenType.EQ);
347-
final ContainerAccessExpression containerExpr = (ContainerAccessExpression) qualifiedNameExpr;
348-
return new ContainerAssignmentExpression(containerExpr, expression());
362+
final TokenType currentType = get(0).getType();
363+
if (!assignOperator.containsKey(currentType)) {
364+
pos = position;
365+
return null;
349366
}
350-
pos = position;
367+
match(currentType);
368+
369+
final BinaryExpression.Operator op = assignOperator.get(currentType);
370+
final Expression expression = expression();
351371

352-
return null;
372+
return new AssignmentExpression(op, (Accessible) targetExpr, expression);
353373
}
354374

355375
private Expression ternary() {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public enum TokenType {
3333
STAR, // *
3434
SLASH, // /
3535
PERCENT,// %
36+
3637
EQ, // =
3738
EQEQ, // ==
3839
EXCL, // !
@@ -42,6 +43,19 @@ public enum TokenType {
4243
GT, // >
4344
GTEQ, // >=
4445

46+
PLUSEQ, // +=
47+
MINUSEQ, // -=
48+
STAREQ, // *=
49+
SLASHEQ, // /=
50+
PERCENTEQ, // %=
51+
AMPEQ, // &=
52+
CARETEQ, // ^=
53+
BAREQ, // |=
54+
COLONCOLONEQ, // ::=
55+
LTLTEQ, // <<=
56+
GTGTEQ, // >>=
57+
GTGTGTEQ, // >>>=
58+
4559
LTLT, // <<
4660
GTGT, // >>
4761
GTGTGT, // >>>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.annimon.ownlang.parser.ast;
2+
3+
import com.annimon.ownlang.lib.Value;
4+
5+
public interface Accessible {
6+
7+
Value get();
8+
9+
Value set(Value value);
10+
}
Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
package com.annimon.ownlang.parser.ast;
22

33
import com.annimon.ownlang.lib.Value;
4-
import com.annimon.ownlang.lib.Variables;
54

65
/**
76
*
87
* @author aNNiMON
98
*/
109
public final class AssignmentExpression implements Expression {
1110

12-
public final String variable;
11+
public final Accessible target;
12+
public final BinaryExpression.Operator operation;
1313
public final Expression expression;
14-
15-
public AssignmentExpression(String variable, Expression expression) {
16-
this.variable = variable;
17-
this.expression = expression;
18-
}
1914

15+
public AssignmentExpression(BinaryExpression.Operator operation, Accessible target, Expression expr) {
16+
this.operation = operation;
17+
this.target = target;
18+
this.expression = expr;
19+
}
20+
2021
@Override
2122
public Value eval() {
22-
final Value result = expression.eval();
23-
Variables.set(variable, result);
24-
return result;
23+
if (operation == null) {
24+
// Simple assignment
25+
return target.set(expression.eval());
26+
}
27+
final Expression expr1 = new ValueExpression(target.get());
28+
final Expression expr2 = new ValueExpression(expression.eval());
29+
return target.set(new BinaryExpression(operation, expr1, expr2).eval());
2530
}
2631

2732
@Override
@@ -31,6 +36,7 @@ public void accept(Visitor visitor) {
3136

3237
@Override
3338
public String toString() {
34-
return String.format("%s = %s", variable, expression);
39+
final String op = (operation == null) ? "" : operation.toString();
40+
return String.format("%s %s= %s", target, op, expression);
3541
}
3642
}

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
* @author aNNiMON
1010
*/
11-
public final class ContainerAccessExpression implements Expression {
11+
public final class ContainerAccessExpression implements Expression, Accessible {
1212

1313
public final String variable;
1414
public final List<Expression> indices;
@@ -20,6 +20,11 @@ public ContainerAccessExpression(String variable, List<Expression> indices) {
2020

2121
@Override
2222
public Value eval() {
23+
return get();
24+
}
25+
26+
@Override
27+
public Value get() {
2328
final Value container = getContainer();
2429
final Value lastIndex = lastIndex();
2530
switch (container.type()) {
@@ -31,7 +36,26 @@ public Value eval() {
3136
return ((MapValue) container).get(lastIndex);
3237

3338
default:
34-
throw new TypeException("Array or map expected");
39+
throw new TypeException("Array or map expected. Got " + container.type());
40+
}
41+
}
42+
43+
@Override
44+
public Value set(Value value) {
45+
final Value container = getContainer();
46+
final Value lastIndex = lastIndex();
47+
switch (container.type()) {
48+
case Types.ARRAY:
49+
final int arrayIndex = (int) lastIndex.asNumber();
50+
((ArrayValue) container).set(arrayIndex, value);
51+
return value;
52+
53+
case Types.MAP:
54+
((MapValue) container).set(lastIndex, value);
55+
return value;
56+
57+
default:
58+
throw new TypeException("Array or map expected. Got " + container.type());
3559
}
3660
}
3761

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

Lines changed: 0 additions & 55 deletions
This file was deleted.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ public ValueExpression(String value) {
2525
public ValueExpression(Function value) {
2626
this.value = new FunctionValue(value);
2727
}
28+
29+
public ValueExpression(Value value) {
30+
this.value = value;
31+
}
2832

2933
@Override
3034
public Value eval() {

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
* @author aNNiMON
1010
*/
11-
public final class VariableExpression implements Expression {
11+
public final class VariableExpression implements Expression, Accessible {
1212

1313
public final String name;
1414

@@ -18,9 +18,20 @@ public VariableExpression(String name) {
1818

1919
@Override
2020
public Value eval() {
21+
return get();
22+
}
23+
24+
@Override
25+
public Value get() {
2126
if (!Variables.isExists(name)) throw new VariableDoesNotExistsException(name);
2227
return Variables.get(name);
2328
}
29+
30+
@Override
31+
public Value set(Value value) {
32+
Variables.set(name, value);
33+
return value;
34+
}
2435

2536
@Override
2637
public void accept(Visitor visitor) {

0 commit comments

Comments
 (0)