Showing with 2,412 additions and 1,414 deletions.
  1. +238 −0 src/main/java/openmods/calc/BasicCompilerMapFactory.java
  2. +35 −172 src/main/java/openmods/calc/Calculator.java
  3. +24 −0 src/main/java/openmods/calc/Compilers.java
  4. +57 −0 src/main/java/openmods/calc/Environment.java
  5. +25 −0 src/main/java/openmods/calc/ExecutableList.java
  6. +13 −0 src/main/java/openmods/calc/ExprType.java
  7. +5 −1 src/main/java/openmods/calc/GenericFunctions.java
  8. +7 −0 src/main/java/openmods/calc/ICompilerMapFactory.java
  9. +5 −0 src/main/java/openmods/calc/IValuePrinter.java
  10. +2 −11 src/main/java/openmods/calc/OperatorDictionary.java
  11. +24 −0 src/main/java/openmods/calc/PrinterUtils.java
  12. +31 −0 src/main/java/openmods/calc/SimpleCalculatorFactory.java
  13. +11 −3 src/main/java/openmods/calc/SymbolReference.java
  14. +15 −2 src/main/java/openmods/calc/TopFrame.java
  15. +40 −81 src/main/java/openmods/calc/command/CalcState.java
  16. +4 −4 src/main/java/openmods/calc/command/CommandCalcConfig.java
  17. +1 −1 src/main/java/openmods/calc/command/CommandCalcEvaluate.java
  18. +6 −6 src/main/java/openmods/calc/parsing/AstCompiler.java
  19. +102 −0 src/main/java/openmods/calc/parsing/DefaultExecutableListBuilder.java
  20. +7 −22 src/main/java/openmods/calc/parsing/DefaultExprNodeFactory.java
  21. +50 −0 src/main/java/openmods/calc/parsing/DefaultPostfixCompiler.java
  22. +0 −55 src/main/java/openmods/calc/parsing/DelegateExprNodeFactory.java
  23. +0 −48 src/main/java/openmods/calc/parsing/EmptyExprNodeFactory.java
  24. +1 −1 src/main/java/openmods/calc/parsing/IAstParser.java
  25. +0 −5 src/main/java/openmods/calc/parsing/IAstParserProvider.java
  26. +24 −0 src/main/java/openmods/calc/parsing/ICompilerState.java
  27. +21 −0 src/main/java/openmods/calc/parsing/IExecutableListBuilder.java
  28. +2 −6 src/main/java/openmods/calc/parsing/IExprNodeFactory.java
  29. +0 −5 src/main/java/openmods/calc/parsing/IModifierExprNodeFactory.java
  30. +19 −0 src/main/java/openmods/calc/parsing/IPostfixCompilerState.java
  31. +0 −7 src/main/java/openmods/calc/parsing/ISymbolExprNodeFactory.java
  32. +1 −1 src/main/java/openmods/calc/parsing/{ICompiler.java → ITokenStreamCompiler.java}
  33. +18 −19 src/main/java/openmods/calc/parsing/InfixParser.java
  34. +52 −74 src/main/java/openmods/calc/parsing/PostfixCompiler.java
  35. +27 −31 src/main/java/openmods/calc/parsing/PrefixParser.java
  36. +13 −10 src/main/java/openmods/calc/parsing/QuotedParser.java
  37. +71 −0 src/main/java/openmods/calc/parsing/SimplePostfixCompilerState.java
  38. +116 −116 src/main/java/openmods/calc/types/bigint/{BigIntCalculator.java → BigIntCalculatorFactory.java}
  39. +62 −42 src/main/java/openmods/calc/types/bigint/BigIntPrinter.java
  40. +121 −130 src/main/java/openmods/calc/types/fp/{DoubleCalculator.java → DoubleCalculatorFactory.java}
  41. +87 −59 src/main/java/openmods/calc/types/fp/DoublePrinter.java
  42. +89 −87 ...main/java/openmods/calc/types/fraction/{FractionCalculator.java → FractionCalculatorFactory.java}
  43. +21 −0 src/main/java/openmods/calc/types/fraction/FractionPrinter.java
  44. +69 −39 src/main/java/openmods/calc/types/multi/{QuotedExprNodeFactory.java → QuoteStateTransition.java}
  45. +276 −300 ...ain/java/openmods/calc/types/multi/{TypedValueCalculator.java → TypedValueCalculatorFactory.java}
  46. +138 −0 src/main/java/openmods/calc/types/multi/TypedValuePrinter.java
  47. +12 −0 src/main/java/openmods/calc/types/multi/UnitType.java
  48. +42 −3 src/test/java/openmods/calc/BigIntCalculatorTest.java
  49. +1 −1 src/test/java/openmods/calc/BigIntPrinterTest.java
  50. +133 −40 src/test/java/openmods/calc/CalcTestUtils.java
  51. +42 −3 src/test/java/openmods/calc/DoubleCalculatorTest.java
  52. +1 −1 src/test/java/openmods/calc/DoublePrinterTest.java
  53. +43 −3 src/test/java/openmods/calc/FractionCalculatorTest.java
  54. +5 −4 src/test/java/openmods/calc/InfixCompilerTest.java
  55. +110 −2 src/test/java/openmods/calc/PostfixCompilerTest.java
  56. +10 −9 src/test/java/openmods/calc/PrefixCompilerTest.java
  57. +83 −10 src/test/java/openmods/calc/TypedValueCalculatorTest.java
@@ -0,0 +1,238 @@
package openmods.calc;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.PeekingIterator;
import java.util.List;
import java.util.Map;
import openmods.calc.Compilers.ICompiler;
import openmods.calc.parsing.AstCompiler;
import openmods.calc.parsing.DefaultExecutableListBuilder;
import openmods.calc.parsing.DefaultExprNodeFactory;
import openmods.calc.parsing.DefaultPostfixCompiler;
import openmods.calc.parsing.DefaultPostfixCompiler.IStateProvider;
import openmods.calc.parsing.DummyNode;
import openmods.calc.parsing.IAstParser;
import openmods.calc.parsing.ICompilerState;
import openmods.calc.parsing.ICompilerState.ISymbolStateTransition;
import openmods.calc.parsing.IExprNode;
import openmods.calc.parsing.IExprNodeFactory;
import openmods.calc.parsing.IPostfixCompilerState;
import openmods.calc.parsing.ITokenStreamCompiler;
import openmods.calc.parsing.IValueParser;
import openmods.calc.parsing.InfixParser;
import openmods.calc.parsing.PrefixParser;
import openmods.calc.parsing.SimplePostfixCompilerState;
import openmods.calc.parsing.SymbolNode;
import openmods.calc.parsing.Token;
import openmods.calc.parsing.TokenType;
import openmods.calc.parsing.TokenUtils;
import openmods.calc.parsing.Tokenizer;

public class BasicCompilerMapFactory<E> implements ICompilerMapFactory<E, ExprType> {

public static final String BRACKET_CONSTANT_EVALUATE = "[";
public static final String SYMBOL_PREFIX = "prefix";
public static final String SYMBOL_INFIX = "infix";

public static class ConstantEvaluatingCompilerState<E> implements IStateProvider<E> {
private final IValueParser<E> valueParser;
private final OperatorDictionary<E> operators;
private final Environment<E> env;
private final String openingBracket;
private boolean isFinished;

public ConstantEvaluatingCompilerState(IValueParser<E> valueParser, OperatorDictionary<E> operators, Environment<E> env, String openingBracket) {
this.valueParser = valueParser;
this.operators = operators;
this.env = env;
this.openingBracket = openingBracket;
}

@Override
public IPostfixCompilerState<E> createState() {
return new SimplePostfixCompilerState<E>(new DefaultExecutableListBuilder<E>(valueParser, operators)) {

@Override
public Result acceptToken(Token token) {
if (token.type == TokenType.RIGHT_BRACKET) {
TokenUtils.checkIsValidBracketPair(openingBracket, token.value);
isFinished = true;
return Result.ACCEPTED_AND_FINISHED;
}
return super.acceptToken(token);
}

@Override
public IExecutable<E> exit() {
Preconditions.checkState(isFinished, "Missing closing bracket");
final IExecutable<E> compiledExpr = super.exit();
final TopFrame<E> resultFrame = env.executeIsolated(compiledExpr);
final List<IExecutable<E>> computedValues = Lists.newArrayList();
for (E value : resultFrame.stack())
computedValues.add(Value.create(value));
return new ExecutableList<E>(computedValues);
}

};
}
}

private static class WrappedCompiler<E> implements ICompiler<E> {
private final Tokenizer tokenizer;
private final ITokenStreamCompiler<E> compiler;

private WrappedCompiler(Tokenizer tokenizer, ITokenStreamCompiler<E> compiler) {
this.tokenizer = tokenizer;
this.compiler = compiler;
}

@Override
public IExecutable<E> compile(String input) {
final PeekingIterator<Token> tokens = tokenizer.tokenize(input);
final IExecutable<E> result = compiler.compile(tokens);
if (tokens.hasNext())
throw new IllegalStateException("Unconsumed tokens: " + Lists.newArrayList(tokens));

return result;
}
}

public static class ParserSwitchTransition<E> implements ISymbolStateTransition<E> {
private ICompilerState<E> switchState;

public ParserSwitchTransition(ICompilerState<E> switchState) {
this.switchState = switchState;
}

@Override
public ICompilerState<E> getState() {
return switchState;
}

@Override
public IExprNode<E> createRootNode(List<IExprNode<E>> children) {
Preconditions.checkState(children.size() == 1, "Expected one node, got %s", children);
return new DummyNode<E>(children.get(0));
}
}

public static class SwitchingCompilerState<E> implements ICompilerState<E> {

private final IAstParser<E> parser;

private final String currentStateSymbol;
private final String switchStateSymbol;
private ICompilerState<E> switchState;

public SwitchingCompilerState(IAstParser<E> parser, String currentStateSymbol, String switchStateSymbol) {
this.parser = parser;
this.currentStateSymbol = currentStateSymbol;
this.switchStateSymbol = switchStateSymbol;
}

public SwitchingCompilerState<E> setSwitchState(ICompilerState<E> switchState) {
this.switchState = switchState;
return this;
}

@Override
public ISymbolStateTransition<E> getStateForSymbol(final String symbol) {
if (symbol.equals(switchStateSymbol)) return new ParserSwitchTransition<E>(switchState);
if (symbol.equals(currentStateSymbol)) return new ParserSwitchTransition<E>(this);

return new ISymbolStateTransition<E>() {
@Override
public ICompilerState<E> getState() {
return SwitchingCompilerState.this;
}

@Override
public IExprNode<E> createRootNode(List<IExprNode<E>> children) {
return new SymbolNode<E>(symbol, children);
}
};
}

@Override
public IModifierStateTransition<E> getStateForModifier(String modifier) {
throw new UnsupportedOperationException(modifier);
}

@Override
public IAstParser<E> getParser() {
return parser;
}
}

@Override
public Compilers<E, ExprType> create(E nullValue, IValueParser<E> valueParser, OperatorDictionary<E> operators, Environment<E> environment) {
final Tokenizer prefixTokenizer = new Tokenizer();

final Tokenizer infixTokenizer = new Tokenizer();

final Tokenizer postfixTokenizer = new Tokenizer();

for (String operator : operators.allOperators()) {
prefixTokenizer.addOperator(operator);
infixTokenizer.addOperator(operator);
postfixTokenizer.addOperator(operator);
}

setupPrefixTokenizer(prefixTokenizer);
setupInfixTokenizer(infixTokenizer);
setupPostfixTokenizer(postfixTokenizer);

final IExprNodeFactory<E> exprNodeFactory = createExprNodeFactory(valueParser);
final SwitchingCompilerState<E> prefixCompilerState = createPrefixCompilerState(operators, exprNodeFactory);
final SwitchingCompilerState<E> infixCompilerState = createInfixParserState(operators, exprNodeFactory);

infixCompilerState.setSwitchState(prefixCompilerState);
prefixCompilerState.setSwitchState(infixCompilerState);

final Map<ExprType, ICompiler<E>> compilers = Maps.newHashMap();
compilers.put(ExprType.PREFIX, new WrappedCompiler<E>(prefixTokenizer, createPrefixParser(prefixCompilerState)));
compilers.put(ExprType.INFIX, new WrappedCompiler<E>(infixTokenizer, createInfixParser(infixCompilerState)));
compilers.put(ExprType.POSTFIX, new WrappedCompiler<E>(postfixTokenizer, createPostfixParser(valueParser, operators, environment)));
return new Compilers<E, ExprType>(compilers);
}

protected void setupPrefixTokenizer(Tokenizer tokenizer) {}

protected SwitchingCompilerState<E> createPrefixCompilerState(OperatorDictionary<E> operators, IExprNodeFactory<E> exprNodeFactory) {
final IAstParser<E> prefixParser = new PrefixParser<E>(operators, exprNodeFactory);
return new SwitchingCompilerState<E>(prefixParser, SYMBOL_PREFIX, SYMBOL_INFIX);
}

protected ITokenStreamCompiler<E> createPrefixParser(ICompilerState<E> compilerState) {
return new AstCompiler<E>(compilerState);
}

protected void setupInfixTokenizer(Tokenizer tokenizer) {}

protected SwitchingCompilerState<E> createInfixParserState(OperatorDictionary<E> operators, IExprNodeFactory<E> exprNodeFactory) {
final IAstParser<E> infixParser = new InfixParser<E>(operators, exprNodeFactory);
return new SwitchingCompilerState<E>(infixParser, SYMBOL_INFIX, SYMBOL_PREFIX);
}

protected ITokenStreamCompiler<E> createInfixParser(ICompilerState<E> compilerState) {
return new AstCompiler<E>(compilerState);
}

protected void setupPostfixTokenizer(Tokenizer tokenizer) {}

protected ITokenStreamCompiler<E> createPostfixParser(final IValueParser<E> valueParser, final OperatorDictionary<E> operators, final Environment<E> env) {
final DefaultPostfixCompiler<E> compiler = new DefaultPostfixCompiler<E>(valueParser, operators);
return addConstantEvaluatorState(valueParser, operators, env, compiler);
}

public static <E> DefaultPostfixCompiler<E> addConstantEvaluatorState(final IValueParser<E> valueParser, final OperatorDictionary<E> operators, final Environment<E> env, final DefaultPostfixCompiler<E> compiler) {
return compiler.addBracketStateProvider(BRACKET_CONSTANT_EVALUATE, new ConstantEvaluatingCompilerState<E>(valueParser, operators, env, BRACKET_CONSTANT_EVALUATE));
}

protected DefaultExprNodeFactory<E> createExprNodeFactory(IValueParser<E> valueParser) {
return new DefaultExprNodeFactory<E>(valueParser);
}

}