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 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("match", TokenType.MATCH);
|
||||
KEYWORDS.put("case", TokenType.CASE);
|
||||
KEYWORDS.put("extract", TokenType.EXTRACT);
|
||||
}
|
||||
|
||||
private final String input;
|
||||
|
@ -87,6 +87,9 @@ public final class Parser {
|
||||
if (match(TokenType.MATCH)) {
|
||||
return new ExprStatement(match());
|
||||
}
|
||||
if (match(TokenType.EXTRACT)) {
|
||||
return destructuringAssignment();
|
||||
}
|
||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
|
||||
return new ExprStatement(function(qualifiedName()));
|
||||
}
|
||||
@ -107,6 +110,22 @@ public final class Parser {
|
||||
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() {
|
||||
final Expression condition = expression();
|
||||
final Statement ifStatement = statementOrBlock();
|
||||
|
@ -26,6 +26,7 @@ public enum TokenType {
|
||||
USE,
|
||||
MATCH,
|
||||
CASE,
|
||||
EXTRACT,
|
||||
|
||||
PLUS, // +
|
||||
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(ContinueStatement s);
|
||||
void visit(DoWhileStatement s);
|
||||
void visit(DestructuringAssignmentStatement s);
|
||||
void visit(ForStatement s);
|
||||
void visit(ForeachArrayStatement s);
|
||||
void visit(ForeachMapStatement s);
|
||||
|
@ -61,6 +61,11 @@ public abstract class AbstractVisitor implements Visitor {
|
||||
@Override
|
||||
public void visit(ContinueStatement s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DestructuringAssignmentStatement s) {
|
||||
s.containerExpression.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DoWhileStatement s) {
|
||||
|
Loading…
Reference in New Issue
Block a user