Урок 12. Многомерные массивы

This commit is contained in:
Victor 2015-06-27 13:58:02 +03:00
parent c678d5d5e1
commit 5144524ba2
5 changed files with 72 additions and 41 deletions

View File

@ -54,7 +54,10 @@ arr = [1, "text", sum(10, 15), [], ["text", [90, [7 + 6, [50]]]]]
print arr + "\n"
arr[0] = arr[0] + 1000 + arr[2]
print arr + "\n"
arr4 = arr[4]
print arr4 + "\n"
arr41 = arr4[1]
print arr41 + "\n"
print arr[4][1] + "\n"
arr[4][1] = "text"
print arr[4][1] + "\n"
print "\n\n"
array = newarray(2, 2, 2, 2)
print array

View File

@ -31,8 +31,28 @@ public final class Functions {
}
return NumberValue.ZERO;
});
functions.put("newarray", args -> {
return new ArrayValue(args);
functions.put("newarray", new Function() {
@Override
public Value execute(Value... args) {
return createArray(args, 0);
}
private ArrayValue createArray(Value[] args, int index) {
final int size = (int) args[index].asNumber();
final int last = args.length - 1;
ArrayValue array = new ArrayValue(size);
if (index == last) {
for (int i = 0; i < size; i++) {
array.set(i, NumberValue.ZERO);
}
} else if (index < last) {
for (int i = 0; i < size; i++) {
array.set(i, createArray(args, index + 1));
}
}
return array;
}
});
}

View File

@ -86,12 +86,9 @@ public final class Parser {
return new AssignmentStatement(variable, expression());
}
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LBRACKET)) {
final String variable = consume(TokenType.WORD).getText();
consume(TokenType.LBRACKET);
final Expression index = expression();
consume(TokenType.RBRACKET);
final ArrayAccessExpression array = element();
consume(TokenType.EQ);
return new ArrayAssignmentStatement(variable, index, expression());
return new ArrayAssignmentStatement(array, expression());
}
throw new RuntimeException("Unknown statement");
}
@ -164,12 +161,15 @@ public final class Parser {
return new ArrayExpression(elements);
}
private Expression element() {
private ArrayAccessExpression element() {
final String variable = consume(TokenType.WORD).getText();
final List<Expression> indices = new ArrayList<>();
do {
consume(TokenType.LBRACKET);
final Expression index = expression();
indices.add(expression());
consume(TokenType.RBRACKET);
return new ArrayAccessExpression(variable, index);
} while(lookMatch(0, TokenType.LBRACKET));
return new ArrayAccessExpression(variable, indices);
}
private Expression expression() {

View File

@ -3,6 +3,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables;
import java.util.List;
/**
*
@ -11,19 +12,38 @@ import com.annimon.ownlang.lib.Variables;
public final class ArrayAccessExpression implements Expression {
private final String variable;
private final Expression index;
private final List<Expression> indices;
public ArrayAccessExpression(String variable, Expression index) {
public ArrayAccessExpression(String variable, List<Expression> indices) {
this.variable = variable;
this.index = index;
this.indices = indices;
}
@Override
public Value eval() {
final Value var = Variables.get(variable);
if (var instanceof ArrayValue) {
final ArrayValue array = (ArrayValue) var;
return array.get((int) index.eval().asNumber());
return getArray().get(lastIndex());
}
public ArrayValue getArray() {
ArrayValue array = consumeArray(Variables.get(variable));
final int last = indices.size() - 1;
for (int i = 0; i < last; i++) {
array = consumeArray( array.get(index(i)) );
}
return array;
}
public int lastIndex() {
return index(indices.size() - 1);
}
private int index(int index) {
return (int) indices.get(index).eval().asNumber();
}
private ArrayValue consumeArray(Value value) {
if (value instanceof ArrayValue) {
return (ArrayValue) value;
} else {
throw new RuntimeException("Array expected");
}
@ -31,6 +51,6 @@ public final class ArrayAccessExpression implements Expression {
@Override
public String toString() {
return String.format("%s[%s]", variable, index);
return variable + indices;
}
}

View File

@ -1,38 +1,26 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.Variables;
/**
*
* @author aNNiMON
*/
public final class ArrayAssignmentStatement implements Statement {
private final String variable;
private final Expression index;
private final ArrayAccessExpression array;
private final Expression expression;
public ArrayAssignmentStatement(String variable, Expression index, Expression expression) {
this.variable = variable;
this.index = index;
public ArrayAssignmentStatement(ArrayAccessExpression array, Expression expression) {
this.array = array;
this.expression = expression;
}
@Override
public void execute() {
final Value var = Variables.get(variable);
if (var instanceof ArrayValue) {
final ArrayValue array = (ArrayValue) var;
array.set((int) index.eval().asNumber(), expression.eval());
} else {
throw new RuntimeException("Array expected");
}
array.getArray().set(array.lastIndex(), expression.eval());
}
@Override
public String toString() {
return String.format("%s[%s] = %s", variable, index, expression);
return String.format("%s = %s", array, expression);
}
}