diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-04-18 17:22:36 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-04-18 17:22:36 -0400 |
| commit | bf5f97983a7cd58e5d1147d6d6d93c2b307fe0fb (patch) | |
| tree | 3d1e41c8a7b9cfa5f32c5708a3a223f4e7ee5e8f /dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java | |
| parent | 24f3ce54983348e1aa0229d5c08b3fe99d739d40 (diff) | |
Implemented arrays
Diffstat (limited to 'dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java')
| -rw-r--r-- | dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java | 134 |
1 files changed, 120 insertions, 14 deletions
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<Integer, ITree<IDiceASTNode>> apply( - IFunctionalList<IPair<Integer, ITree<IDiceASTNode>>> nodes) { - IPair<Integer, ITree<IDiceASTNode>> initState = - new Pair<>(0, new Tree<>(type)); + public IPair<IResult, ITree<IDiceASTNode>> apply( + IFunctionalList<IPair<IResult, ITree<IDiceASTNode>>> nodes) { + IPair<IResult, ITree<IDiceASTNode>> initState = + new Pair<>(new IntegerResult(0), new Tree<>(type)); - BinaryOperator<IPair<Integer, ITree<IDiceASTNode>>> reducer = + BinaryOperator<IPair<IResult, ITree<IDiceASTNode>>> 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<Integer, ITree<IDiceASTNode>> reducedState = + IPair<IResult, ITree<IDiceASTNode>> reducedState = nodes.reduceAux(initState, reducer, (state) -> state); return reducedState; } - private IPair<Integer, ITree<IDiceASTNode>> reduceStates( - IPair<Integer, ITree<IDiceASTNode>> accumulatedState, - IPair<Integer, ITree<IDiceASTNode>> currentState) { + private IPair<IResult, ITree<IDiceASTNode>> reduceStates( + IPair<IResult, ITree<IDiceASTNode>> accumulatedState, + IPair<IResult, ITree<IDiceASTNode>> 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<IResult, ITree<IDiceASTNode>> doArithmeticCollapse( + IResult accumulatedValue, ITree<IDiceASTNode> accumulatedTree, + IResult currentValue) { + boolean currentIsInt = + currentValue.getType() == ResultType.INTEGER; + boolean accumulatedIsInt = + accumulatedValue.getType() == ResultType.INTEGER; + + if (!currentIsInt) { + if (!accumulatedIsInt) { + IFunctionalList<IResult> resultList = combineArrayResults( + accumulatedValue, currentValue); + + return new Pair<>(new ArrayResult(resultList), + accumulatedTree); + } + + IFunctionalList<IResult> resultList = halfCombineLists( + ((ArrayResult) currentValue).getValue(), + accumulatedValue, true); + + return new Pair<>(new ArrayResult(resultList), + accumulatedTree); + } else if (!accumulatedIsInt) { + IFunctionalList<IResult> 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<IResult> combineArrayResults( + IResult accumulatedValue, IResult currentValue) { + IFunctionalList<IResult> currentList = + ((ArrayResult) currentValue).getValue(); + IFunctionalList<IResult> accumulatedList = + ((ArrayResult) accumulatedValue).getValue(); + + if (currentList.getSize() != accumulatedList.getSize()) { + throw new UnsupportedOperationException( + "Can only apply operations to equal-length arrays"); + } + + IFunctionalList<IResult> 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<IResult> halfCombineLists( + IFunctionalList<IResult> 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 |
