mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Реструктуризующее присваивание
This commit is contained in:
parent
95c71753ca
commit
9536c7f5b0
13
program.own
13
program.own
@ -185,4 +185,15 @@ println class.add(2, class.mul(2, 2))
|
|||||||
println split("1/2/3/4/5/6", "/")
|
println split("1/2/3/4/5/6", "/")
|
||||||
println join(nums, ", ")
|
println join(nums, ", ")
|
||||||
println join(nums, "|", "/")
|
println join(nums, "|", "/")
|
||||||
println join(nums, ", ", "[", "]")
|
println join(nums, ", ", "[", "]")
|
||||||
|
|
||||||
|
// Destructuring assignment
|
||||||
|
arr = ["a", "b", "c"]
|
||||||
|
extract(var1, var2, var3) = arr
|
||||||
|
echo(var1, var2, var3)
|
||||||
|
// Swap
|
||||||
|
extract(var2, var1) = [var1, var2]
|
||||||
|
echo(var1, var2)
|
||||||
|
|
||||||
|
extract(, , var4) = arr
|
||||||
|
println var4
|
@ -74,6 +74,7 @@ public final class Lexer {
|
|||||||
KEYWORDS.put("use", TokenType.USE);
|
KEYWORDS.put("use", TokenType.USE);
|
||||||
KEYWORDS.put("match", TokenType.MATCH);
|
KEYWORDS.put("match", TokenType.MATCH);
|
||||||
KEYWORDS.put("case", TokenType.CASE);
|
KEYWORDS.put("case", TokenType.CASE);
|
||||||
|
KEYWORDS.put("extract", TokenType.EXTRACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
@ -87,6 +87,9 @@ public final class Parser {
|
|||||||
if (match(TokenType.MATCH)) {
|
if (match(TokenType.MATCH)) {
|
||||||
return new ExprStatement(match());
|
return new ExprStatement(match());
|
||||||
}
|
}
|
||||||
|
if (match(TokenType.EXTRACT)) {
|
||||||
|
return destructuringAssignment();
|
||||||
|
}
|
||||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
|
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
|
||||||
return new ExprStatement(function(qualifiedName()));
|
return new ExprStatement(function(qualifiedName()));
|
||||||
}
|
}
|
||||||
@ -107,6 +110,22 @@ public final class Parser {
|
|||||||
throw new ParseException("Unknown statement: " + get(0));
|
throw new ParseException("Unknown statement: " + get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DestructuringAssignmentStatement destructuringAssignment() {
|
||||||
|
// extract(var1, var2, ...) = ...
|
||||||
|
consume(TokenType.LPAREN);
|
||||||
|
final List<String> variables = new ArrayList<>();
|
||||||
|
while (!match(TokenType.RPAREN)) {
|
||||||
|
if (lookMatch(0, TokenType.WORD)) {
|
||||||
|
variables.add(consume(TokenType.WORD).getText());
|
||||||
|
} else {
|
||||||
|
variables.add(null);
|
||||||
|
}
|
||||||
|
match(TokenType.COMMA);
|
||||||
|
}
|
||||||
|
consume(TokenType.EQ);
|
||||||
|
return new DestructuringAssignmentStatement(variables, expression());
|
||||||
|
}
|
||||||
|
|
||||||
private Statement ifElse() {
|
private Statement ifElse() {
|
||||||
final Expression condition = expression();
|
final Expression condition = expression();
|
||||||
final Statement ifStatement = statementOrBlock();
|
final Statement ifStatement = statementOrBlock();
|
||||||
|
@ -26,6 +26,7 @@ public enum TokenType {
|
|||||||
USE,
|
USE,
|
||||||
MATCH,
|
MATCH,
|
||||||
CASE,
|
CASE,
|
||||||
|
EXTRACT,
|
||||||
|
|
||||||
PLUS, // +
|
PLUS, // +
|
||||||
MINUS, // -
|
MINUS, // -
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.annimon.ownlang.parser.ast;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.ArrayValue;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
import com.annimon.ownlang.lib.Variables;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public final class DestructuringAssignmentStatement implements Statement {
|
||||||
|
|
||||||
|
public final List<String> variables;
|
||||||
|
public final Expression containerExpression;
|
||||||
|
|
||||||
|
public DestructuringAssignmentStatement(List<String> arguments, Expression container) {
|
||||||
|
this.variables = arguments;
|
||||||
|
this.containerExpression = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
final Value container = containerExpression.eval();
|
||||||
|
switch (container.type()) {
|
||||||
|
case Types.ARRAY:
|
||||||
|
execute((ArrayValue) container);
|
||||||
|
break;
|
||||||
|
case Types.MAP:
|
||||||
|
execute((MapValue) container);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execute(ArrayValue array) {
|
||||||
|
final int size = variables.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
final String variable = variables.get(i);
|
||||||
|
if (variable != null) {
|
||||||
|
Variables.set(variable, array.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void execute(MapValue map) {
|
||||||
|
int i = 0;
|
||||||
|
for (Map.Entry<Value, Value> entry : map) {
|
||||||
|
final String variable = variables.get(i);
|
||||||
|
if (variable != null) {
|
||||||
|
Variables.set(variable, new ArrayValue(
|
||||||
|
new Value[] { entry.getKey(), entry.getValue() }
|
||||||
|
));
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return variables.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ public interface Visitor {
|
|||||||
void visit(ConditionalExpression s);
|
void visit(ConditionalExpression s);
|
||||||
void visit(ContinueStatement s);
|
void visit(ContinueStatement s);
|
||||||
void visit(DoWhileStatement s);
|
void visit(DoWhileStatement s);
|
||||||
|
void visit(DestructuringAssignmentStatement s);
|
||||||
void visit(ForStatement s);
|
void visit(ForStatement s);
|
||||||
void visit(ForeachArrayStatement s);
|
void visit(ForeachArrayStatement s);
|
||||||
void visit(ForeachMapStatement s);
|
void visit(ForeachMapStatement s);
|
||||||
|
@ -61,6 +61,11 @@ public abstract class AbstractVisitor implements Visitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(ContinueStatement s) {
|
public void visit(ContinueStatement s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(DestructuringAssignmentStatement s) {
|
||||||
|
s.containerExpression.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoWhileStatement s) {
|
public void visit(DoWhileStatement s) {
|
||||||
|
Loading…
Reference in New Issue
Block a user