+static void genEqOp(int op, struct Parser* p, struct Token* t)
+{
+ int cidx, n = 2, setop = genLValue(p, LEFT(t), &cidx);
+ if(setop == OP_SETMEMBER) {
+ emit(p, OP_DUP2);
+ emit(p, OP_POP);
+ emitImmediate(p, OP_MEMBER, cidx);
+ } else if(setop == OP_INSERT) {
+ emit(p, OP_DUP2);
+ emit(p, OP_EXTRACT);
+ } else {
+ emitImmediate(p, OP_LOCAL, cidx);
+ n = 1;
+ }
+ genExpr(p, RIGHT(t));
+ emit(p, op);
+ emit(p, n == 1 ? OP_XCHG : OP_XCHG2);
+ emit(p, setop);
+}
+
+static int defArg(struct Parser* p, struct Token* t)
+{
+ if(t->type == TOK_LPAR) return defArg(p, RIGHT(t));
+ if(t->type == TOK_MINUS && RIGHT(t) &&
+ RIGHT(t)->type == TOK_LITERAL && !RIGHT(t)->str)
+ {
+ /* default arguments are constants, but "-1" parses as two
+ * tokens, so we have to subset the expression generator for that
+ * case */
+ RIGHT(t)->num *= -1;
+ return defArg(p, RIGHT(t));
+ }
+ return findConstantIndex(p, t);
+}
+
+static void genArgList(struct Parser* p, struct naCode* c, struct Token* t)
+{
+ naRef sym;
+ if(t->type == TOK_EMPTY) return;
+ if(!IDENTICAL(p->cg->restArgSym, globals->argRef))
+ naParseError(p, "remainder must be last", t->line);
+ if(t->type == TOK_ELLIPSIS) {
+ if(LEFT(t)->type != TOK_SYMBOL)
+ naParseError(p, "bad function argument expression", t->line);
+ sym = naStr_fromdata(naNewString(p->context),
+ LEFT(t)->str, LEFT(t)->strlen);
+ p->cg->restArgSym = naInternSymbol(sym);
+ c->needArgVector = 1;
+ } else if(t->type == TOK_ASSIGN) {
+ if(LEFT(t)->type != TOK_SYMBOL)
+ naParseError(p, "bad function argument expression", t->line);
+ p->cg->optArgSyms[c->nOptArgs] = findConstantIndex(p, LEFT(t));
+ p->cg->optArgVals[c->nOptArgs++] = defArg(p, RIGHT(t));
+ } else if(t->type == TOK_SYMBOL) {
+ if(c->nOptArgs)
+ naParseError(p, "optional arguments must be last", t->line);
+ if(c->nArgs >= MAX_FUNARGS)
+ naParseError(p, "too many named function arguments", t->line);
+ p->cg->argSyms[c->nArgs++] = findConstantIndex(p, t);
+ } else if(t->type == TOK_COMMA) {
+ if(!LEFT(t) || !RIGHT(t))
+ naParseError(p, "empty function argument", t->line);
+ genArgList(p, c, LEFT(t));
+ genArgList(p, c, RIGHT(t));
+ } else
+ naParseError(p, "bad function argument expression", t->line);
+}
+
+static naRef newLambda(struct Parser* p, struct Token* t)