From 5144524ba2f2eaab81739897c4691c126ac9c130 Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 27 Jun 2015 13:58:02 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D1=80=D0=BE=D0=BA=2012.=20=D0=9C=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=D0=BC=D0=B5=D1=80=D0=BD=D1=8B=D0=B5=20=D0=BC?= =?UTF-8?q?=D0=B0=D1=81=D1=81=D0=B8=D0=B2=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- program.own | 11 +++--- src/com/annimon/ownlang/lib/Functions.java | 24 +++++++++++-- src/com/annimon/ownlang/parser/Parser.java | 20 +++++------ .../parser/ast/ArrayAccessExpression.java | 36 ++++++++++++++----- .../parser/ast/ArrayAssignmentStatement.java | 22 +++--------- 5 files changed, 72 insertions(+), 41 deletions(-) diff --git a/program.own b/program.own index b9d2446..234db83 100644 --- a/program.own +++ b/program.own @@ -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" \ No newline at end of file +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 \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/Functions.java b/src/com/annimon/ownlang/lib/Functions.java index c840f58..161abea 100644 --- a/src/com/annimon/ownlang/lib/Functions.java +++ b/src/com/annimon/ownlang/lib/Functions.java @@ -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; + } }); } diff --git a/src/com/annimon/ownlang/parser/Parser.java b/src/com/annimon/ownlang/parser/Parser.java index 9940143..5e25f07 100644 --- a/src/com/annimon/ownlang/parser/Parser.java +++ b/src/com/annimon/ownlang/parser/Parser.java @@ -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(); - consume(TokenType.LBRACKET); - final Expression index = expression(); - consume(TokenType.RBRACKET); - return new ArrayAccessExpression(variable, index); + final List indices = new ArrayList<>(); + do { + consume(TokenType.LBRACKET); + indices.add(expression()); + consume(TokenType.RBRACKET); + } while(lookMatch(0, TokenType.LBRACKET)); + return new ArrayAccessExpression(variable, indices); } private Expression expression() { diff --git a/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java b/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java index 87519bc..d71e09b 100644 --- a/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java +++ b/src/com/annimon/ownlang/parser/ast/ArrayAccessExpression.java @@ -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 indices; - public ArrayAccessExpression(String variable, Expression index) { + public ArrayAccessExpression(String variable, List 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; } } diff --git a/src/com/annimon/ownlang/parser/ast/ArrayAssignmentStatement.java b/src/com/annimon/ownlang/parser/ast/ArrayAssignmentStatement.java index 838bd7c..29e6820 100644 --- a/src/com/annimon/ownlang/parser/ast/ArrayAssignmentStatement.java +++ b/src/com/annimon/ownlang/parser/ast/ArrayAssignmentStatement.java @@ -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); } }