package jscl.text;
import jscl.math.Generic;
import jscl.math.function.Function;
import jscl.math.function.FunctionsRegistry;
import jscl.math.function.ImplicitFunction;
import jscl.math.operator.matrix.OperatorsRegistry;
import jscl.text.msg.Messages;
import jscl.util.ArrayUtils;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ImplicitFunctionParser implements Parser<Function> {
public static final Parser<Function> parser = new ImplicitFunctionParser();
private ImplicitFunctionParser() {
}
public Function parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue();
Generic a[];
final String name = ParserUtils.parseWithRollback(CompoundIdentifier.parser, pos0, previousSumElement, p);
if (FunctionsRegistry.getInstance().getNames().contains(name) || OperatorsRegistry.getInstance().getNames().contains(name)) {
p.position.setValue(pos0);
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_6, Collections.singletonList(name));
}
final List<Generic> subscripts = new ArrayList<Generic>();
while (true) {
try {
subscripts.add(Subscript.parser.parse(p, previousSumElement));
} catch (ParseException e) {
p.exceptionsPool.release(e);
break;
}
}
int b[];
try {
b = Derivation.parser.parse(p, previousSumElement);
} catch (ParseException e) {
p.exceptionsPool.release(e);
b = new int[0];
}
try {
a = ParameterListParser.parser1.parse(p, previousSumElement);
} catch (ParseException e) {
p.position.setValue(pos0);
throw e;
}
int derivations[] = new int[a.length];
for (int i = 0; i < a.length && i < b.length; i++) {
derivations[i] = b[i];
}
return new ImplicitFunction(name, a, derivations, ArrayUtils.toArray(subscripts, new Generic[subscripts.size()]));
}
}
class Derivation implements Parser<int[]> {
public static final Parser<int[]> parser = new Derivation();
private Derivation() {
}
public int[] parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
try {
return new int[]{PrimeCharacters.parser.parse(p, previousSumElement)};
} catch (ParseException e) {
p.exceptionsPool.release(e);
}
return SuperscriptList.parser.parse(p, previousSumElement);
}
}
class SuperscriptList implements Parser<int[]> {
public static final Parser<int[]> parser = new SuperscriptList();
private SuperscriptList() {
}
public int[] parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue();
ParserUtils.tryToParse(p, pos0, '{');
final List<Integer> result = new ArrayList<Integer>();
try {
result.add(IntegerParser.parser.parse(p, previousSumElement));
} catch (ParseException e) {
p.position.setValue(pos0);
throw e;
}
while (true) {
try {
result.add(CommaAndInteger.parser.parse(p, previousSumElement));
} catch (ParseException e) {
p.exceptionsPool.release(e);
break;
}
}
ParserUtils.tryToParse(p, pos0, '}');
ParserUtils.skipWhitespaces(p);
return ArrayUtils.toArray(result, new int[result.size()]);
}
}
class CommaAndInteger implements Parser<Integer> {
public static final Parser<Integer> parser = new CommaAndInteger();
private CommaAndInteger() {
}
public Integer parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue();
ParserUtils.skipWhitespaces(p);
return ParserUtils.parseWithRollback(IntegerParser.parser, pos0, previousSumElement, p);
}
}