mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Pattern matching по значениям списка
This commit is contained in:
parent
b957569759
commit
726e96488a
@ -38,3 +38,28 @@ def printArrayRecursive(arr) = match arr {
|
|||||||
case []: "[]"
|
case []: "[]"
|
||||||
case last: "[" + last + ", []]"
|
case last: "[" + last + ", []]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println "\nPattern matching on arrays by value"
|
||||||
|
def tupleMatch(x) = match x {
|
||||||
|
case (0, 0): "00"
|
||||||
|
case (1, 0): "10"
|
||||||
|
case (0, 1): "01"
|
||||||
|
case (1, 1): "11"
|
||||||
|
case (2, _): "2?"
|
||||||
|
case _: "unknown"
|
||||||
|
}
|
||||||
|
println tupleMatch([0, 1])
|
||||||
|
println tupleMatch([1, 1])
|
||||||
|
println tupleMatch([2, 1])
|
||||||
|
println tupleMatch([3, 9])
|
||||||
|
|
||||||
|
|
||||||
|
println "\nFizzBuzz with pattern matching"
|
||||||
|
for i = 1, i <= 100, i++ {
|
||||||
|
println match [i % 3 == 0, i % 5 == 0] {
|
||||||
|
case (true, false): "Fizz"
|
||||||
|
case (false, true): "Buzz"
|
||||||
|
case (true, true): "FizzBuzz"
|
||||||
|
case _: i
|
||||||
|
}
|
||||||
|
}
|
@ -368,6 +368,19 @@ public final class Parser {
|
|||||||
match(TokenType.COLONCOLON);
|
match(TokenType.COLONCOLON);
|
||||||
}
|
}
|
||||||
pattern = listPattern;
|
pattern = listPattern;
|
||||||
|
} else if (match(TokenType.LPAREN)) {
|
||||||
|
// case (1, 2):
|
||||||
|
final MatchExpression.TuplePattern tuplePattern = new MatchExpression.TuplePattern();
|
||||||
|
while (!match(TokenType.RPAREN)) {
|
||||||
|
if ("_".equals(get(0).getText())) {
|
||||||
|
tuplePattern.addAny();
|
||||||
|
consume(TokenType.WORD);
|
||||||
|
} else {
|
||||||
|
tuplePattern.add(expression());
|
||||||
|
}
|
||||||
|
match(TokenType.COMMA);
|
||||||
|
}
|
||||||
|
pattern = tuplePattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern == null) {
|
if (pattern == null) {
|
||||||
|
@ -7,6 +7,7 @@ import com.annimon.ownlang.lib.Types;
|
|||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
import com.annimon.ownlang.lib.Variables;
|
import com.annimon.ownlang.lib.Variables;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +50,7 @@ public final class MatchExpression implements Expression, Statement {
|
|||||||
} else {
|
} else {
|
||||||
Variables.define(pattern.variable, value);
|
Variables.define(pattern.variable, value);
|
||||||
if (optMatches(p)) {
|
if (optMatches(p)) {
|
||||||
final Value result = evalResult(p.result);;
|
final Value result = evalResult(p.result);
|
||||||
Variables.remove(pattern.variable);
|
Variables.remove(pattern.variable);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -67,10 +68,29 @@ public final class MatchExpression implements Expression, Statement {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((value.type() == Types.ARRAY) && (p instanceof TuplePattern)) {
|
||||||
|
final TuplePattern pattern = (TuplePattern) p;
|
||||||
|
if (matchTuplePattern((ArrayValue) value, pattern) && optMatches(p)) {
|
||||||
|
return evalResult(p.result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new PatternMatchingException("No pattern were matched");
|
throw new PatternMatchingException("No pattern were matched");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean matchTuplePattern(ArrayValue array, TuplePattern p) {
|
||||||
|
if (p.values.size() != array.size()) return false;
|
||||||
|
|
||||||
|
final int size = array.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
final Expression expr = p.values.get(i);
|
||||||
|
if ( (expr != TuplePattern.ANY) && (expr.eval().compareTo(array.get(i)) != 0) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean matchListPattern(ArrayValue array, ListPattern p) {
|
private boolean matchListPattern(ArrayValue array, ListPattern p) {
|
||||||
final List<String> parts = p.parts;
|
final List<String> parts = p.parts;
|
||||||
final int partsSize = parts.size();
|
final int partsSize = parts.size();
|
||||||
@ -232,7 +252,73 @@ public final class MatchExpression implements Expression, Statement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return parts + ": " + result;
|
final Iterator<String> it = parts.iterator();
|
||||||
|
if (it.hasNext()) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("[").append(it.next());
|
||||||
|
while (it.hasNext()) {
|
||||||
|
sb.append(" :: ").append(it.next());
|
||||||
|
}
|
||||||
|
sb.append("]: ").append(result);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
return "[]: " + result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TuplePattern extends Pattern {
|
||||||
|
public List<Expression> values;
|
||||||
|
|
||||||
|
public TuplePattern() {
|
||||||
|
this(new ArrayList<Expression>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TuplePattern(List<Expression> parts) {
|
||||||
|
this.values = parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAny() {
|
||||||
|
values.add(ANY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Expression value) {
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final Iterator<Expression> it = values.iterator();
|
||||||
|
if (it.hasNext()) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("(").append(it.next());
|
||||||
|
while (it.hasNext()) {
|
||||||
|
sb.append(", ").append(it.next());
|
||||||
|
}
|
||||||
|
sb.append("): ").append(result);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
return "(): " + result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Expression ANY = new Expression() {
|
||||||
|
@Override
|
||||||
|
public Value eval() {
|
||||||
|
return NumberValue.ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, T> R accept(ResultVisitor<R, T> visitor, T input) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "_";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user