int st = cursor;
captureToNextTokenJunction();
if (cursor == end) {
throw new CompileException("unexpected end of statement", expr, st);
}
/**
* Check to see if the name is legal.
*/
if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st))
|| isNotValidNameorLabel(name))
throw new CompileException("illegal function name or use of reserved word", expr, cursor);
if (pCtx == null) pCtx = getParserContext();
FunctionParser parser = new FunctionParser(name, cursor, end - cursor, expr, fields, pCtx, splitAccumulator);
Function function = parser.parse();
cursor = parser.getCursor();
return lastNode = function;
}
case PROTO: {
if (ProtoParser.isUnresolvedWaiting()) {
if (pCtx == null) pCtx = getParserContext();
ProtoParser.checkForPossibleUnresolvedViolations(expr, cursor, pCtx);
}
int st = cursor;
captureToNextTokenJunction();
if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st))
|| isNotValidNameorLabel(name))
throw new CompileException("illegal prototype name or use of reserved word", expr, cursor);
if (expr[cursor = nextNonBlank()] != '{') {
throw new CompileException("expected '{' but found: " + expr[cursor], expr, cursor);
}
cursor = balancedCaptureWithLineAccounting(expr, st = cursor + 1, end, '{', pCtx);
if (pCtx == null) pCtx = getParserContext();
ProtoParser parser = new ProtoParser(expr, st, cursor, name, pCtx, fields, splitAccumulator);
Proto proto = parser.parse();
if (pCtx == null) pCtx = getParserContext();
pCtx.addImport(proto);
proto.setCursorPosition(st, cursor);
cursor = parser.getCursor();
ProtoParser.notifyForLateResolution(proto);
return lastNode = proto;
}
case STACKLANG: {
if (expr[cursor = nextNonBlank()] != '{') {
throw new CompileException("expected '{' but found: " + expr[cursor], expr, cursor);
}
int st;
cursor = balancedCaptureWithLineAccounting(expr, st = cursor + 1, end, '{', pCtx);
if (pCtx == null) pCtx = getParserContext();
Stacklang stacklang = new Stacklang(expr, st, cursor - st, fields, pCtx);
cursor++;
return lastNode = stacklang;
}
default:
if (cond) {
if (expr[cursor] != '(') {
throw new CompileException("expected '(' but encountered: " + expr[cursor], expr, cursor);
}
/**
* This block is an: IF, FOREACH or WHILE node.
*/
endCond = cursor = balancedCaptureWithLineAccounting(expr, startCond = cursor, end, '(', pCtx);
startCond++;
cursor++;
}
}
skipWhitespace();
if (cursor >= end) {
throw new CompileException("unexpected end of statement", expr, end);
}
else if (expr[cursor] == '{') {
blockEnd = cursor = balancedCaptureWithLineAccounting(expr, blockStart = cursor, end, '{', pCtx);
}
else {
blockStart = cursor - 1;
captureToEOSorEOL();
blockEnd = cursor + 1;
}
if (type == ASTNode.BLOCK_IF) {
IfNode ifNode = (IfNode) node;
if (node != null) {
if (!cond) {
return ifNode.setElseBlock(expr, st = trimRight(blockStart + 1), trimLeft(blockEnd) - st, pCtx);
}
else {
return ifNode.setElseIf((IfNode) createBlockToken(startCond, endCond, trimRight(blockStart + 1),
trimLeft(blockEnd), type));
}
}
else {
return createBlockToken(startCond, endCond, blockStart + 1, blockEnd, type);
}
}
else if (type == ASTNode.BLOCK_DO) {
cursor++;
skipWhitespace();
st = cursor;
captureToNextTokenJunction();
if ("while".equals(name = new String(expr, st, cursor - st))) {
skipWhitespace();
startCond = cursor + 1;
endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
}
else if ("until".equals(name)) {
skipWhitespace();
startCond = cursor + 1;
endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd),
ASTNode.BLOCK_DO_UNTIL);
}
else {
throw new CompileException("expected 'while' or 'until' but encountered: " + name, expr, cursor);
}
}
// DON"T REMOVE THIS COMMENT!
// else if (isFlag(ASTNode.BLOCK_FOREACH) || isFlag(ASTNode.BLOCK_WITH)) {
else {