package org.matheclipse.core.reflection.system;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.exception.WrappedException;
import org.matheclipse.core.eval.exception.WrongArgumentType;
import org.matheclipse.core.eval.interfaces.IFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.ISymbol;
public class Part implements IFunctionEvaluator {
public Part() {
}
public IExpr evaluate(final IAST ast) {
if (ast.size() >= 3) {
// if (ast.arg1() == F.Null) {
// System.out.println("Part argument is null");
// }
if (ast.arg1().isAST()) {
return getPart(ast.getAST(1), ast, 2);
}
}
return null;
}
private IExpr getPart(final IExpr expr1, final IAST ast, int pos) {
if (!expr1.isAST()) {
throw new WrongArgumentType(ast, expr1, pos, "Wrong argument for Part[] function. Function or list expected.");
}
IAST arg1 = (IAST) expr1;
final IExpr arg2 = ast.get(pos);
int p1 = pos + 1;
IExpr temp = null;
if (arg2.isSignedNumber()) {
final int indx = Validate.checkIntType(ast, pos, Integer.MIN_VALUE);
IExpr ires = null;
ires = getIndex(arg1, indx);
if (p1 < ast.size()) {
return getPart(ires, ast, p1);
}
return ires;
} else if (arg2.isList()) {
final IAST lst = (IAST) arg2;
final IAST result = F.List();
for (int i = 1; i < lst.size(); i++) {
final IExpr expr = lst.get(i);
if (expr.isInteger()) {
IExpr ires = null;
final int indx = Validate.checkIntType(lst, i, Integer.MIN_VALUE);
ires = getIndex(arg1, indx);
if (ires == null) {
return null;
}
if (p1 < ast.size()) {
temp = getPart(ires, ast, p1);
result.add(temp);
} else {
result.add(ires);
}
}
}
return result;
}
throw new WrongArgumentType(ast, arg2, pos, "Wrong argument for Part[] function");
}
/**
* Get the element stored at the given position.
*
* @param ast
* @param position
* @return
*/
IExpr getIndex(IAST ast, int position) {
if (position < 0) {
position = ast.size() + position;
}
if ((position < 0) || (position >= ast.size())) {
throw new WrappedException(new IndexOutOfBoundsException("Part[] index " + position + " of " + ast.toString()
+ " is out of bounds."));
}
return ast.get(position);
}
public IExpr numericEval(final IAST functionList) {
return evaluate(functionList);
}
public void setUp(final ISymbol symbol) {
symbol.setAttributes(ISymbol.NHOLDREST);
}
}
Ads help maintain this website.