Skip to content

Commit 802927e

Browse files
committed
Присваивание как выражение
1 parent cb07629 commit 802927e

File tree

8 files changed

+59
-32
lines changed

8 files changed

+59
-32
lines changed

program.own

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,7 @@ def funcWithOptionalArgs(str, count = 5, prefix = "<", suffix = ">") = prefix +
217217

218218
println funcWithOptionalArgs("*")
219219
println funcWithOptionalArgs("+", 2)
220-
println funcWithOptionalArgs("*", 10, "<!")
220+
println funcWithOptionalArgs("*", 10, "<!")
221+
222+
v1 = v2 = v3 = v4 = 5
223+
echo(v1, v2, v3, v4)

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

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,27 +87,19 @@ private Statement statement() {
8787
if (match(TokenType.MATCH)) {
8888
return new ExprStatement(match());
8989
}
90-
if (match(TokenType.EXTRACT)) {
91-
return destructuringAssignment();
92-
}
9390
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
9491
return new ExprStatement(function(qualifiedName()));
9592
}
9693
return assignmentStatement();
9794
}
9895

9996
private Statement assignmentStatement() {
100-
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.EQ)) {
101-
final String variable = consume(TokenType.WORD).getText();
102-
consume(TokenType.EQ);
103-
return new AssignmentStatement(variable, expression());
97+
if (match(TokenType.EXTRACT)) {
98+
return destructuringAssignment();
10499
}
105-
106-
final Expression qualifiedNameExpr = qualifiedName();
107-
if (lookMatch(0, TokenType.EQ) && (qualifiedNameExpr instanceof ContainerAccessExpression)) {
108-
consume(TokenType.EQ);
109-
final ContainerAccessExpression containerExpr = (ContainerAccessExpression) qualifiedNameExpr;
110-
return new ContainerAssignmentStatement(containerExpr, expression());
100+
final Expression assignment = assignmentStrict();
101+
if (assignment != null) {
102+
return new ExprStatement(assignment);
111103
}
112104
throw new ParseException("Unknown statement: " + get(0));
113105
}
@@ -330,9 +322,36 @@ private MatchExpression match() {
330322
}
331323

332324
private Expression expression() {
325+
return assignment();
326+
}
327+
328+
private Expression assignment() {
329+
final Expression assignment = assignmentStrict();
330+
if (assignment != null) {
331+
return assignment;
332+
}
333333
return ternary();
334334
}
335335

336+
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());
341+
}
342+
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());
349+
}
350+
pos = position;
351+
352+
return null;
353+
}
354+
336355
private Expression ternary() {
337356
Expression result = logicalOr();
338357

src/com/annimon/ownlang/parser/ast/AssignmentStatement.java renamed to src/com/annimon/ownlang/parser/ast/AssignmentExpression.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@
77
*
88
* @author aNNiMON
99
*/
10-
public final class AssignmentStatement implements Statement {
10+
public final class AssignmentExpression implements Expression {
1111

1212
public final String variable;
1313
public final Expression expression;
1414

15-
public AssignmentStatement(String variable, Expression expression) {
15+
public AssignmentExpression(String variable, Expression expression) {
1616
this.variable = variable;
1717
this.expression = expression;
1818
}
1919

2020
@Override
21-
public void execute() {
21+
public Value eval() {
2222
final Value result = expression.eval();
2323
Variables.set(variable, result);
24+
return result;
2425
}
2526

2627
@Override

src/com/annimon/ownlang/parser/ast/ContainerAssignmentStatement.java renamed to src/com/annimon/ownlang/parser/ast/ContainerAssignmentExpression.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,33 @@
1010
*
1111
* @author aNNiMON
1212
*/
13-
public final class ContainerAssignmentStatement implements Statement {
13+
public final class ContainerAssignmentExpression implements Expression {
1414

1515
public final ContainerAccessExpression containerExpr;
1616
public final Expression expression;
1717

18-
public ContainerAssignmentStatement(ContainerAccessExpression array, Expression expression) {
18+
public ContainerAssignmentExpression(ContainerAccessExpression array, Expression expression) {
1919
this.containerExpr = array;
2020
this.expression = expression;
2121
}
2222

2323
@Override
24-
public void execute() {
24+
public Value eval() {
2525
final Value container = containerExpr.getContainer();
2626
final Value lastIndex = containerExpr.lastIndex();
2727
switch (container.type()) {
28-
case Types.ARRAY:
28+
case Types.ARRAY: {
29+
final Value result = expression.eval();
2930
final int arrayIndex = (int) lastIndex.asNumber();
30-
((ArrayValue) container).set(arrayIndex, expression.eval());
31-
return;
31+
((ArrayValue) container).set(arrayIndex, result);
32+
return result;
33+
}
3234

33-
case Types.MAP:
34-
((MapValue) container).set(lastIndex, expression.eval());
35-
return;
35+
case Types.MAP: {
36+
final Value result = expression.eval();
37+
((MapValue) container).set(lastIndex, result);
38+
return result;
39+
}
3640

3741
default:
3842
throw new TypeException("Array or map expected. Got " + container.type());

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
public interface Visitor {
88

99
void visit(ArrayExpression s);
10-
void visit(AssignmentStatement s);
10+
void visit(AssignmentExpression s);
1111
void visit(BinaryExpression s);
1212
void visit(BlockStatement s);
1313
void visit(BreakStatement s);
1414
void visit(ConditionalExpression s);
1515
void visit(ContainerAccessExpression s);
16-
void visit(ContainerAssignmentStatement s);
16+
void visit(ContainerAssignmentExpression s);
1717
void visit(ContinueStatement s);
1818
void visit(DoWhileStatement s);
1919
void visit(DestructuringAssignmentStatement s);

src/com/annimon/ownlang/parser/visitors/AbstractVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public void visit(ArrayExpression s) {
1818
}
1919

2020
@Override
21-
public void visit(AssignmentStatement s) {
21+
public void visit(AssignmentExpression s) {
2222
s.expression.accept(this);
2323
}
2424

@@ -53,7 +53,7 @@ public void visit(ContainerAccessExpression s) {
5353
}
5454

5555
@Override
56-
public void visit(ContainerAssignmentStatement s) {
56+
public void visit(ContainerAssignmentExpression s) {
5757
s.containerExpr.accept(this);
5858
s.expression.accept(this);
5959
}

src/com/annimon/ownlang/parser/visitors/AssignValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
public final class AssignValidator extends AbstractVisitor {
1111

1212
@Override
13-
public void visit(AssignmentStatement s) {
13+
public void visit(AssignmentExpression s) {
1414
super.visit(s);
1515
if (Variables.isExists(s.variable)) {
1616
throw new RuntimeException("Cannot assign value to constant");

src/com/annimon/ownlang/parser/visitors/VariablePrinter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
public final class VariablePrinter extends AbstractVisitor {
1010

1111
@Override
12-
public void visit(AssignmentStatement s) {
12+
public void visit(AssignmentExpression s) {
1313
super.visit(s);
1414
System.out.println(s.variable);
1515
}

0 commit comments

Comments
 (0)