use of org.apfloat.Apfloat in project symja_android_library by axkr.
the class AST2Expr method convertNode.
/**
* Converts a parsed ASTNode expression into an IExpr expression
*
* @param engine
* TODO
*/
private IExpr convertNode(ASTNode node, EvalEngine engine) throws ConversionException {
if (node == null) {
return null;
}
if (node instanceof FunctionNode) {
final FunctionNode functionNode = (FunctionNode) node;
int size = functionNode.size();
IAST ast;
switch(size) {
case 1:
ast = F.headAST0(convertNode(functionNode.get(0), engine));
break;
case 2:
ast = F.unaryAST1(convertNode(functionNode.get(0), engine), convertNode(functionNode.get(1), engine));
break;
case 3:
ast = F.binaryAST2(convertNode(functionNode.get(0), engine), convertNode(functionNode.get(1), engine), convertNode(functionNode.get(2), engine));
break;
case 4:
ast = F.ternaryAST3(convertNode(functionNode.get(0), engine), convertNode(functionNode.get(1), engine), convertNode(functionNode.get(2), engine), convertNode(functionNode.get(3), engine));
break;
default:
ast = F.ast(convertNode(functionNode.get(0), engine), functionNode.size(), false);
for (int i = 1; i < functionNode.size(); i++) {
ast.append(convertNode(functionNode.get(i), engine));
}
}
IExpr head = ast.head();
if (ast.isAST(F.N, 3)) {
try {
int precision = Validate.checkIntType(ast.arg2());
if (EvalEngine.isApfloat(precision)) {
fPrecision = precision;
ast.set(1, convertNode(functionNode.get(1), engine));
}
return ast;
} catch (WrongArgumentType wat) {
}
} else if (ast.isAST(F.Sqrt, 2)) {
// rewrite from input: Sqrt(x) => Power(x, 1/2)
return F.Power(ast.arg1(), F.C1D2);
} else if (ast.isAST(F.Exp, 2)) {
// rewrite from input: Exp(x) => E^x
return F.Power(F.E, ast.arg1());
} else if (ast.isPower() && ast.arg1().isPower() && ast.arg2().isMinusOne()) {
IAST arg1 = (IAST) ast.arg1();
if (arg1.arg2().isNumber()) {
// Power(x, - <number>)
return F.Power(arg1.arg1(), ((INumber) arg1.arg2()).negate());
}
} else if (ast.isASTSizeGE(F.GreaterEqual, 3)) {
ISymbol compareHead = F.Greater;
return rewriteLessGreaterAST(ast, compareHead);
} else if (ast.isASTSizeGE(F.Greater, 3)) {
ISymbol compareHead = F.GreaterEqual;
return rewriteLessGreaterAST(ast, compareHead);
} else if (ast.isASTSizeGE(F.LessEqual, 3)) {
ISymbol compareHead = F.Less;
return rewriteLessGreaterAST(ast, compareHead);
} else if (ast.isASTSizeGE(F.Less, 3)) {
ISymbol compareHead = F.LessEqual;
return rewriteLessGreaterAST(ast, compareHead);
} else if (head.equals(F.PatternHead)) {
final IExpr expr = Pattern.CONST.evaluate(ast, engine);
if (expr.isPresent()) {
return expr;
}
} else if (head.equals(F.BlankHead)) {
final IExpr expr = Blank.CONST.evaluate(ast, engine);
if (expr.isPresent()) {
return expr;
}
} else if (head.equals(F.Complex)) {
final IExpr expr = Arithmetic.CONST_COMPLEX.evaluate(ast, engine);
if (expr.isPresent()) {
return expr;
}
} else if (head.equals(F.Rational)) {
final IExpr expr = Arithmetic.CONST_RATIONAL.evaluate(ast, engine);
if (expr.isPresent()) {
return expr;
}
}
return ast;
}
if (node instanceof SymbolNode) {
String nodeStr = node.getString();
return convertSymbol(nodeStr, engine);
}
// PatternNode
if (node instanceof Pattern3Node) {
final Pattern3Node p3n = (Pattern3Node) node;
SymbolNode sn = p3n.getSymbol();
return F.$ps((ISymbol) convertNode(sn, engine), convertNode(p3n.getConstraint(), engine), p3n.isDefault(), true);
}
if (node instanceof Pattern2Node) {
final Pattern2Node p2n = (Pattern2Node) node;
SymbolNode sn = p2n.getSymbol();
return F.$ps((ISymbol) convertNode(sn, engine), convertNode(p2n.getConstraint(), engine), p2n.isDefault(), false);
}
if (node instanceof PatternNode) {
final PatternNode pn = (PatternNode) node;
SymbolNode sn = pn.getSymbol();
if (sn == null) {
// TODO ,
return F.$b(convertNode(pn.getConstraint(), engine));
// p2n.isDefault());
}
ASTNode defaultValue = pn.getDefaultValue();
if (defaultValue != null) {
return F.$p((ISymbol) convertNode(pn.getSymbol(), engine), convertNode(pn.getConstraint(), engine), convertNode(defaultValue, engine));
}
return F.$p((ISymbol) convertNode(pn.getSymbol(), engine), convertNode(pn.getConstraint(), engine), pn.isDefault());
}
if (node instanceof IntegerNode) {
final IntegerNode integerNode = (IntegerNode) node;
final String iStr = integerNode.getString();
if (iStr != null) {
return F.integer(iStr, integerNode.getNumberFormat());
}
return F.integer(integerNode.getIntValue());
}
if (node instanceof FractionNode) {
FractionNode fr = (FractionNode) node;
IInteger numerator = (IInteger) convertNode(fr.getNumerator(), engine);
IInteger denominator = (IInteger) convertNode(fr.getDenominator(), engine);
if (denominator.isZero()) {
return F.Rational(fr.isSign() ? numerator.negate() : numerator, denominator);
}
return F.Rational(fr.isSign() ? numerator.negate() : numerator, denominator);
// return F.fraction(numerator, fr.isSign() ? (IInteger) denominator.negate() : denominator);
}
if (node instanceof StringNode) {
return F.$str(node.getString());
}
if (node instanceof FloatNode) {
String nStr = node.getString();
String floatStr = nStr;
int index = nStr.indexOf("*^");
int exponent = 1;
if (index > 0) {
floatStr = nStr.substring(0, index);
exponent = Integer.parseInt(nStr.substring(index + 2));
}
if (EvalEngine.isApfloat(fPrecision)) {
Apfloat apfloatValue = new Apfloat(floatStr, fPrecision);
if (exponent != 1) {
// value * 10 ^ exponent
return F.num(apfloatValue.multiply(ApfloatMath.pow(new Apint(10), new Apint(exponent))));
}
return F.num(apfloatValue);
}
double doubleValue = Double.parseDouble(floatStr);
if (exponent != 1) {
// value * 10 ^ exponent
return F.num(doubleValue * Math.pow(10, exponent));
}
return F.num(doubleValue);
}
if (node instanceof DoubleNode) {
return F.num(((DoubleNode) node).doubleValue());
}
return F.userSymbol(node.toString(), engine);
}
Aggregations