FastStringBuffer buf = new FastStringBuffer();
//Temporary buffer for some operations. Must always be cleared before it's used.
FastStringBuffer tempBuf = new FastStringBuffer();
ParsingUtils parsingUtils = ParsingUtils.create(cs, throwSyntaxError);
char lastChar = '\0';
for (int i = 0; i < cs.length; i++) {
char c = cs[i];
switch (c) {
case '\'':
case '"':
//ignore literals and multi-line literals, including comments...
i = parsingUtils.eatLiterals(buf, i, std.trimMultilineLiterals);
break;
case '#':
i = handleComment(std, cs, buf, tempBuf, parsingUtils, i);
break;
case ',':
i = formatForComma(std, cs, buf, i, tempBuf);
break;
case '(':
i = formatForPar(parsingUtils, cs, i, std, buf, parensLevel + 1, delimiter, throwSyntaxError);
break;
//Things to treat:
//+, -, *, /, %
//** // << >>
//<, >, !=, <>, <=, >=, //=, *=, /=,
//& ^ ~ |
case '*':
//for *, we also need to treat when it's used in varargs, kwargs and list expansion
boolean isOperator = false;
for (int j = buf.length() - 1; j >= 0; j--) {
char localC = buf.charAt(j);
if (Character.isWhitespace(localC)) {
continue;
}
if (localC == '(' || localC == ',') {
//it's not an operator, but vararg. kwarg or list expansion
}
if (Character.isJavaIdentifierPart(localC)) {
//ok, there's a chance that it can be an operator, but we still have to check
//the chance that it's a wild import
tempBuf.clear();
while (Character.isJavaIdentifierPart(localC)) {
tempBuf.append(localC);
j--;
if (j < 0) {
break; //break while
}
localC = buf.charAt(j);
}
String reversed = tempBuf.reverse().toString();
if (!reversed.equals("import") && !reversed.equals("lambda")) {
isOperator = true;
}
}
if (localC == '\'' || localC == ')' || localC == ']') {
isOperator = true;
}
//If it got here (i.e.: not whitespace), get out of the for loop.
break;
}
if (!isOperator) {
buf.append('*');
break;//break switch
}
//Otherwise, FALLTHROUGH
case '+':
case '-':
if (c == '-' || c == '+') { // could also be *
//handle exponentials correctly: e.g.: 1e-6 cannot have a space
tempBuf.clear();
boolean started = false;
for (int j = buf.length() - 1;; j--) {
if (j < 0) {
break;
}
char localC = buf.charAt(j);
if (localC == ' ' || localC == '\t') {
if (!started) {
continue;
} else {
break;
}
}
started = true;
if (Character.isJavaIdentifierPart(localC) || localC == '.') {
tempBuf.append(localC);
} else {
break;//break for
}
}
boolean isExponential = true;
String partialNumber = tempBuf.reverse().toString();
int partialLen = partialNumber.length();
if (partialLen < 2 || !Character.isDigit(partialNumber.charAt(0))) {
//at least 2 chars: the number and the 'e'
isExponential = false;
} else {
//first char checked... now, if the last is an 'e', we must leave it together no matter what
if (partialNumber.charAt(partialLen - 1) != 'e'
&& partialNumber.charAt(partialLen - 1) != 'E') {
isExponential = false;
}
}
if (isExponential) {
buf.rightTrim();
buf.append(c);
//skip the next whitespaces from the buffer
int initial = i;
do {
i++;
} while (i < cs.length && (c = cs[i]) == ' ' || c == '\t');
if (i > initial) {
i--;//backup 1 because we walked 1 too much.
}
break;//break switch
}
//Otherwise, FALLTHROUGH
}
case '/':
case '%':
case '<':
case '>':
case '!':
case '&':
case '^':
case '~':
case '|':
i = handleOperator(std, cs, buf, parsingUtils, i, c);
c = cs[i];
break;
//check for = and == (other cases that have an = as the operator should already be treated)
case '=':
if (i < cs.length - 1 && cs[i + 1] == '=') {
//if == handle as if a regular operator
i = handleOperator(std, cs, buf, parsingUtils, i, c);
c = cs[i];
break;
}
while (buf.length() > 0 && buf.lastChar() == ' ') {
buf.deleteLast();
}
boolean surroundWithSpaces = std.operatorsWithSpace;
if (parensLevel > 0) {
surroundWithSpaces = std.assignWithSpaceInsideParens;
}
//add space before
if (surroundWithSpaces) {
buf.append(' ');
}
//add the operator and the '='
buf.append('=');
//add space after
if (surroundWithSpaces) {
buf.append(' ');
}
i = parsingUtils.eatWhitespaces(null, i + 1);
break;
default:
if (c == '\r' || c == '\n') {
if (lastChar == ',' && std.spaceAfterComma && buf.lastChar() == ' ') {