b2.add(parserLine, PUT);
while(peekToken() != RP) { // run through the list of argument names
+ numArgs++;
if (peekToken() == NAME) {
consume(NAME); // a named argument
String varName = string;
b2.add(parserLine, DUP); // dup the args array
- b2.add(parserLine, GET, new Integer(numArgs)); // retrieve it from the arguments array
+ b2.add(parserLine, GET, new Integer(numArgs - 1)); // retrieve it from the arguments array
b2.add(parserLine, TOPSCOPE);
b2.add(parserLine, SWAP);
b2.add(parserLine, DECLARE, varName); // declare the name
}
if (peekToken() == RP) break;
consume(COMMA);
- numArgs++;
}
consume(RP);
+ b2.numFormalArgs = numArgs;
b2.add(parserLine, POP); // pop off the arguments array
b2.add(parserLine, POP); // pop off TOPSCOPE
parseBlock(b2, null); // the function body
- if(b2.get(b2.size()-1) != RETURN) {
- b2.add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL
- b2.add(parserLine, RETURN);
- }
+ b2.add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL
+ b2.add(parserLine, RETURN);
break;
}
tok = -1;
switch(tok) {
case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
- case ASSIGN_ADD: case ASSIGN_SUB: case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: {
+ case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: {
b.add(parserLine, GET_PRESERVE);
startExpr(b, precedence[tok]);
+ int size = b.size();
+ if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) {
+ b.add(parserLine, tok);
+ }
// tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc)
b.add(parserLine, tok - 1, tok-1==ADD ? new Integer(2) : null);
b.add(parserLine, PUT);
b.add(parserLine, SWAP);
b.add(parserLine, POP);
+ if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) b.set(size, tok, new Integer(b.size() - size));
break;
}
case INC: case DEC: { // postfix
break;
}
case DOT: {
- consume(NAME);
+ // support foo..bar syntax for foo[""].bar
+ if (peekToken() == DOT) {
+ string = "";
+ } else {
+ consume(NAME);
+ }
b.add(parserLine, LITERAL, string);
continueExprAfterAssignable(b,minPrecedence);
break;