diff --git a/program.own b/program.own index 10fb83b..4f0656e 100644 --- a/program.own +++ b/program.own @@ -91,3 +91,10 @@ print function(map["+"], 4, 5) print "\n" foreach(map, def(op, func) = echo (4, op, 5, "=", func(4,5))) foreach(arr, ::echo) + +arr1 = [1,2,3] +arr1 = arr1 :: 4 +arr2 = [5,6,7] +print arr1 +print "\n" +print arr1 << arr2 \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/ArrayValue.java b/src/com/annimon/ownlang/lib/ArrayValue.java index 9a570df..9c96199 100644 --- a/src/com/annimon/ownlang/lib/ArrayValue.java +++ b/src/com/annimon/ownlang/lib/ArrayValue.java @@ -9,6 +9,24 @@ import java.util.Iterator; */ public final class ArrayValue implements Value, Iterable { + public static ArrayValue add(ArrayValue array, Value value) { + final int last = array.elements.length; + final ArrayValue result = new ArrayValue(last + 1); + System.arraycopy(array.elements, 0, result.elements, 0, last); + result.elements[last] = value; + return result; + } + + public static ArrayValue merge(ArrayValue array1, ArrayValue array2) { + final int length1 = array1.elements.length; + final int length2 = array2.elements.length; + final int length = length1 + length2; + final ArrayValue result = new ArrayValue(length); + System.arraycopy(array1.elements, 0, result.elements, 0, length1); + System.arraycopy(array2.elements, 0, result.elements, length1, length2); + return result; + } + private final Value[] elements; public ArrayValue(int size) { diff --git a/src/com/annimon/ownlang/parser/Parser.java b/src/com/annimon/ownlang/parser/Parser.java index 9fb830b..29e06d0 100644 --- a/src/com/annimon/ownlang/parser/Parser.java +++ b/src/com/annimon/ownlang/parser/Parser.java @@ -356,6 +356,10 @@ public final class Parser { result = new BinaryExpression(BinaryExpression.Operator.SUBTRACT, result, multiplicative()); continue; } + if (match(TokenType.COLONCOLON)) { + result = new BinaryExpression(BinaryExpression.Operator.PUSH, result, multiplicative()); + continue; + } break; } diff --git a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java index 6601197..2e5f8ea 100644 --- a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java +++ b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java @@ -17,6 +17,7 @@ public final class BinaryExpression implements Expression { MULTIPLY("*"), DIVIDE("/"), REMAINDER("%"), + PUSH("::"), // Bitwise AND("&"), OR("|"), @@ -50,23 +51,46 @@ public final class BinaryExpression implements Expression { public Value eval() { final Value value1 = expr1.eval(); final Value value2 = expr2.eval(); - if ( (value1 instanceof StringValue) || (value1 instanceof ArrayValue) ) { - final String string1 = value1.asString(); - switch (operation) { - case MULTIPLY: { - final int iterations = (int) value2.asNumber(); - final StringBuilder buffer = new StringBuilder(); - for (int i = 0; i < iterations; i++) { - buffer.append(string1); - } - return new StringValue(buffer.toString()); - } - case ADD: - default: - return new StringValue(string1 + value2.asString()); - } - } + if (value1 instanceof StringValue) { + return eval((StringValue) value1, value2); + } + if (value1 instanceof ArrayValue) { + return eval((ArrayValue) value1, value2); + } + return eval(value1, value2); + } + + private Value eval(StringValue value1, Value value2) { + final String string1 = value1.asString(); + switch (operation) { + case MULTIPLY: { + final int iterations = (int) value2.asNumber(); + final StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < iterations; i++) { + buffer.append(string1); + } + return new StringValue(buffer.toString()); + } + case ADD: + default: + return new StringValue(string1 + value2.asString()); + } + } + + private Value eval(ArrayValue value1, Value value2) { + switch (operation) { + case LSHIFT: + if (!(value2 instanceof ArrayValue)) + throw new RuntimeException("Cannot merge non array value to array"); + return ArrayValue.merge(value1, (ArrayValue) value2); + case PUSH: + default: + return ArrayValue.add(value1, value2); + } + } + + private Value eval(Value value1, Value value2) { final double number1 = value1.asNumber(); final double number2 = value2.asNumber(); double result;