From bf5f97983a7cd58e5d1147d6d6d93c2b307fe0fb Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 18 Apr 2016 17:22:36 -0400 Subject: Implemented arrays --- .../java/bjc/dicelang/ast/ArithmeticCollapser.java | 134 ++++++++++++++++++--- 1 file changed, 120 insertions(+), 14 deletions(-) (limited to 'dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java') diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java b/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java index 5c00fe2..ad508c8 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java @@ -28,12 +28,12 @@ final class ArithmeticCollapser implements IOperatorCollapser { } @Override - public IPair> apply( - IFunctionalList>> nodes) { - IPair> initState = - new Pair<>(0, new Tree<>(type)); + public IPair> apply( + IFunctionalList>> nodes) { + IPair> initState = + new Pair<>(new IntegerResult(0), new Tree<>(type)); - BinaryOperator>> reducer = + BinaryOperator>> reducer = (currentState, accumulatedState) -> { // Force evaluation of accumulated state to prevent // certain bugs from occuring @@ -42,27 +42,133 @@ final class ArithmeticCollapser implements IOperatorCollapser { return reduceStates(accumulatedState, currentState); }; - IPair> reducedState = + IPair> reducedState = nodes.reduceAux(initState, reducer, (state) -> state); return reducedState; } - private IPair> reduceStates( - IPair> accumulatedState, - IPair> currentState) { + private IPair> reduceStates( + IPair> accumulatedState, + IPair> currentState) { return accumulatedState .bind((accumulatedValue, accumulatedTree) -> { return currentState .bind((currentValue, currentTree) -> { accumulatedTree.addChild(currentTree); - Integer combinedValue = valueOp.apply( - accumulatedValue, currentValue); - - return new Pair<>(combinedValue, - accumulatedTree); + return doArithmeticCollapse( + accumulatedValue, accumulatedTree, + currentValue); }); }); } + + private IPair> doArithmeticCollapse( + IResult accumulatedValue, ITree accumulatedTree, + IResult currentValue) { + boolean currentIsInt = + currentValue.getType() == ResultType.INTEGER; + boolean accumulatedIsInt = + accumulatedValue.getType() == ResultType.INTEGER; + + if (!currentIsInt) { + if (!accumulatedIsInt) { + IFunctionalList resultList = combineArrayResults( + accumulatedValue, currentValue); + + return new Pair<>(new ArrayResult(resultList), + accumulatedTree); + } + + IFunctionalList resultList = halfCombineLists( + ((ArrayResult) currentValue).getValue(), + accumulatedValue, true); + + return new Pair<>(new ArrayResult(resultList), + accumulatedTree); + } else if (!accumulatedIsInt) { + IFunctionalList resultList = halfCombineLists( + ((ArrayResult) accumulatedValue).getValue(), + currentValue, false); + + return new Pair<>(new ArrayResult(resultList), + accumulatedTree); + } + + int accumulatedInt = ((IntegerResult) accumulatedValue).getValue(); + int currentInt = ((IntegerResult) currentValue).getValue(); + + int combinedValue = valueOp.apply(accumulatedInt, currentInt); + + return new Pair<>(new IntegerResult(combinedValue), + accumulatedTree); + } + + private IFunctionalList combineArrayResults( + IResult accumulatedValue, IResult currentValue) { + IFunctionalList currentList = + ((ArrayResult) currentValue).getValue(); + IFunctionalList accumulatedList = + ((ArrayResult) accumulatedValue).getValue(); + + if (currentList.getSize() != accumulatedList.getSize()) { + throw new UnsupportedOperationException( + "Can only apply operations to equal-length arrays"); + } + + IFunctionalList resultList = currentList.combineWith( + accumulatedList, (currentNode, accumulatedNode) -> { + boolean currentNotInt = + currentNode.getType() != ResultType.INTEGER; + boolean accumulatedNotInt = accumulatedNode + .getType() != ResultType.INTEGER; + + if (currentNotInt || accumulatedNotInt) { + throw new UnsupportedOperationException( + "Nesting of array operations isn't allowed"); + } + + int accumulatedInt = + ((IntegerResult) accumulatedNode).getValue(); + int currentInt = + ((IntegerResult) currentNode).getValue(); + + IResult combinedValue = new IntegerResult( + valueOp.apply(accumulatedInt, currentInt)); + return combinedValue; + }); + return resultList; + } + + private IFunctionalList halfCombineLists( + IFunctionalList list, IResult scalar, + boolean scalarLeft) { + if (scalar.getType() != ResultType.INTEGER) { + throw new UnsupportedOperationException( + "Nested array operations not supported"); + } + + int scalarInt = ((IntegerResult) scalar).getValue(); + + return list.map((element) -> { + if (element.getType() != ResultType.INTEGER) { + throw new UnsupportedOperationException( + "Nested array operations not supported"); + } + int elementInt = ((IntegerResult) element).getValue(); + + IResult combinedValue; + + if (scalarLeft) { + combinedValue = new IntegerResult( + valueOp.apply(scalarInt, elementInt)); + } else { + combinedValue = new IntegerResult( + valueOp.apply(elementInt, scalarInt)); + } + + return combinedValue; + }); + } } \ No newline at end of file -- cgit v1.2.3