static void simpleexp (LexState *ls, expdesc *v) { /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VKNUM, 0); v->u.nval = ls->t.seminfo.r; break; } case TK_STRING: { codestring(ls, v, ls->t.seminfo.ts); break; } case TK_NIL: { init_exp(v, VNIL, 0); break; } case TK_TRUE: { init_exp(v, VTRUE, 0); break; } case TK_FALSE: { init_exp(v, VFALSE, 0); break; } case TK_DOTS: { /* vararg */ FuncState *fs = ls->fs; check_condition(ls, fs->f->is_vararg, "cannot use " LUA_QL("...") " outside a vararg function"); fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } case '{': { /* constructor */ constructor(ls, v); return; } case TK_FUNCTION: { luaX_next(ls); body(ls, v, 0, ls->linenumber); return; } default: { primaryexp(ls, v); return; } } luaX_next(ls); }
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = ls->fs; Proto *f = fs->f; int oldsize = f->sizep; int i; #if LUA_MEMORY_STATS luaM_setname(ls->L, "lua.parser.closures"); #endif /* LUA_MEMORY_STATS */ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "constant table overflow"); #if LUA_MEMORY_STATS luaM_setname(ls->L, 0); #endif /* LUA_MEMORY_STATS */ while (oldsize < f->sizep) f->p[oldsize++] = NULL; f->p[fs->np++] = func->f; #if LUA_REFCOUNT /* already got a reference */ /* luarc_addrefproto(func->f); */ #endif /* LUA_REFCOUNT */ luaC_objbarrier(ls->L, f, func->f); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); for (i=0; i<func->f->nups; i++) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } }
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' explist1 */ int nexps; checknext(ls, '='); nexps = explist1(ls, &e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) ls->fs->freereg -= nexps - nvars; /* remove extra values */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e); }
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = GetCurrentFuncState( ls ); Proto *f = fs->f; int oldsize = f->sizep; luaM_growvector(ls->L, f->p, fs->np, f->sizep, MAXARG_Bx, "constant table overflow"); while ( oldsize < f->sizep ) { f->p[ oldsize++ ] = NULL; } f->p[ fs->np++ ] = func->f; luaC_objbarrier( ls->L, f, func->f ); init_exp( v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1) ); for ( int i = 0; i < func->f->nups; i++ ) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } }
static void constructor(LexState* ls, expdesc* t) { /* constructor -> ?? */ FuncState* fs = ls->fs; int line = ls->linenumber; int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); struct ConsControl cc; cc.na = cc.nh = cc.tostore = 0; cc.t = t; init_exp(t, VRELOCABLE, pc); init_exp(&cc.v, VVOID, 0); /* no value (yet) */ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ checknext(ls, '{'); do { lua_assert(cc.v.k == VVOID || cc.tostore > 0); if (ls->t.token == '}') break; closelistfield(fs, &cc); switch (ls->t.token) { case TK_NAME: /* may be listfields or recfields */ { luaX_lookahead(ls); if (ls->lookahead.token != '=') /* expression? */ listfield(ls, &cc); else recfield(ls, &cc); break; } case '[': /* constructor_item -> recfield */ { recfield(ls, &cc); break; } default: /* constructor_part -> listfield */ { listfield(ls, &cc); break; } } } while (testnext(ls, ',') || testnext(ls, ';')); check_match(ls, '}', '{', line); lastlistfield(fs, &cc); SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ }
static void localfunc (LexState *ls) { expdesc v, b; new_localvar(ls, str_checkname(ls), 0); init_exp(&v, VLOCAL, ls->fs->freereg++); adjustlocalvars(ls, 1); body(ls, &b, 0, ls->linenumber); luaK_storevar(ls->fs, &v, &b); }
static void localstat (LexState *ls) { /* stat -> LOCAL NAME {`,' NAME} [ IN primaryexp | `=' explist1] */ int nvars = 0; int nexps; expdesc e; do { new_localvar(ls, str_checkname(ls), nvars++); } while (testnext(ls, ',')); if (testnext(ls, TK_IN)) { lu_byte from_var; int regs = ls->fs->freereg; int vars = ls->fs->nactvar; luaK_reserveregs(ls->fs, nvars); adjustlocalvars(ls, nvars); new_localvarliteral(ls, "(from)", 0); primaryexp(ls, &e); luaK_exp2nextreg(ls->fs, &e); from_var = ls->fs->nactvar; adjustlocalvars(ls, 1); luaK_setoneret(ls->fs, &e); /* close last expression */ for (nexps=0; nexps<nvars; nexps++) { expdesc v, key; init_exp(&e, VNONRELOC, ls->fs->freereg-1); codestring(ls, &key, getlocvar(ls->fs, vars+nexps).varname); luaK_indexed(ls->fs, &e, &key); init_exp(&v, VLOCAL, regs+nexps); luaK_storevar(ls->fs, &v, &e); } removevars(ls, from_var); return; } if (testnext(ls, '=')) nexps = explist1(ls, &e); else { e.k = VVOID; nexps = 0; } adjust_assign(ls, nvars, nexps, &e); adjustlocalvars(ls, nvars); }
static void simpleexp (LexState *ls, expdesc *v) { /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body | primaryexp */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); next(ls); /* must use `seminfo' before `next' */ break; } case TK_STRING: { codestring(ls, v, ls->t.seminfo.ts); next(ls); /* must use `seminfo' before `next' */ break; } case TK_NIL: { init_exp(v, VNIL, 0); next(ls); break; } case TK_TRUE: { init_exp(v, VTRUE, 0); next(ls); break; } case TK_FALSE: { init_exp(v, VFALSE, 0); next(ls); break; } case '{': { /* constructor */ constructor(ls, v); break; } case TK_FUNCTION: { next(ls); body(ls, v, 0, ls->linenumber); break; } default: { primaryexp(ls, v); break; } } }
static void funcargs(LexState* ls, expdesc* f) { FuncState* fs = ls->fs; expdesc args; int base, nparams; int line = ls->linenumber; switch (ls->t.token) { case '(': /* funcargs -> `(' [ explist1 ] `)' */ { if (line != ls->lastline) luaX_syntaxerror(ls, "ambiguous syntax (function call x new statement)"); luaX_next(ls); if (ls->t.token == ')') /* arg list is empty? */ args.k = VVOID; else { explist1(ls, &args); luaK_setmultret(fs, &args); } check_match(ls, ')', '(', line); break; } case '{': /* funcargs -> constructor */ { constructor(ls, &args); break; } case TK_STRING: /* funcargs -> STRING */ { codestring(ls, &args, ls->t.seminfo.ts); luaX_next(ls); /* must use `seminfo' before `next' */ break; } default: { luaX_syntaxerror(ls, "function arguments expected"); return; } } lua_assert(f->k == VNONRELOC); base = f->u.s.info; /* base register for call */ if (hasmultret(args.k)) nparams = LUA_MULTRET; /* open call */ else { if (args.k != VVOID) luaK_exp2nextreg(fs, &args); /* close last argument */ nparams = fs->freereg - (base + 1); } init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams + 1, 2)); luaK_fixline(fs, line); fs->freereg = base + 1; /* call remove function and arguments and leaves (unless changed) one result */ }
static void localfunc (LexState *ls) { expdesc v, b; FuncState *fs = ls->fs; new_localvar(ls, str_checkname(ls), 0); init_exp(&v, VLOCAL, fs->freereg); luaK_reserveregs(fs, 1); adjustlocalvars(ls, 1); body(ls, &b, 0, ls->linenumber); luaK_storevar(fs, &v, &b); /* debug information will only see the variable after this point! */ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; }
static int assignment (LexState *ls, struct LHS_assign *lh, int nvars, lu_byte *from_var) { expdesc e; int from = 0; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); from = assignment(ls, &nv, nvars+1, from_var); } else { /* assignment -> IN primaryexp | `=' explist1 */ int nexps; if (testnext(ls, TK_IN)) { new_localvarliteral(ls, "(from)", 0); primaryexp(ls, &e); luaK_exp2nextreg(ls->fs, &e); *from_var = ls->fs->nactvar; adjustlocalvars(ls, 1); luaK_setoneret(ls->fs, &e); /* close last expression */ getfrom(ls, &e, &lh->v); luaK_storevar(ls->fs, &lh->v, &e); return 1; /* avoid default */ } else { checknext(ls, '='); nexps = explist1(ls, &e); } if (nexps == nvars) { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); return 0; /* avoid default */ } else { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) ls->fs->freereg -= nexps - nvars; /* remove extra values */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ if (from) getfrom(ls, &e, &lh->v); luaK_storevar(ls->fs, &lh->v, &e); return from; }
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (fs == NULL) { /* no more levels? */ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ return VGLOBAL; } else { int v = searchvar(fs, n); /* look up at current level */ if (v >= 0) { init_exp(var, VLOCAL, v); if (!base) markupval(fs, v); /* local will be used as an upval */ return VLOCAL; } else { /* not found at current level; try upper one */ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) return VGLOBAL; var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ var->k = VUPVAL; /* upvalue in this level */ return VUPVAL; } } }
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = ls->fs; Proto *f = fs->f; int i; luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "constant table overflow"); f->p[fs->np++] = func->f; init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); for (i=0; i<func->f->nups; i++) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } }
/* Find variable with given name 'n'. If it is an upvalue, add this upvalue into all intermediate functions. */ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (fs == NULL) /* no more levels? */ init_exp(var, VVOID, 0); /* default is global */ else { int v = searchvar(fs, n); /* look up locals at current level */ if (v >= 0) { /* found? */ init_exp(var, VLOCAL, v); /* variable is local */ if (!base) markupval(fs, v); /* local will be used as an upval */ } else { /* not found as local at current level; try upvalues */ int idx = searchupvalue(fs, n); /* try existing upvalues */ if (idx < 0) { /* not found? */ singlevaraux(fs->prev, n, var, 0); /* try upper levels */ if (var->k == VVOID) /* not found? */ return; /* it is a global */ /* else was LOCAL or UPVAL */ idx = newupvalue(fs, n, var); /* will be a new upvalue */ } init_exp(var, VUPVAL, idx); /* new or old upvalue */ } } }
static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (fs == NULL) /* no more levels? */ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ else { int v = searchvar(fs, n); /* look up at current level */ if (v >= 0) { init_exp(var, VLOCAL, v); if (!base) markupval(fs, v); /* local will be used as an upval */ } else { /* not found at current level; try upper one */ singlevaraux(fs->prev, n, var, 0); if (var->k == VGLOBAL) { if (base) var->info = luaK_stringK(fs, n); /* info points to global name */ } else { /* LOCAL or UPVAL */ var->info = indexupvalue(fs, n, var); var->k = VUPVAL; /* upvalue in this level */ } } } }
/* Find variable with given name 'n'. If it is an upvalue, add this upvalue into all intermediate functions. */ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (fs == NULL) /* no more levels? */ return VVOID; /* default is global */ else { int v = searchvar(fs, n); /* look up locals at current level */ if (v >= 0) { /* found? */ init_exp(var, VLOCAL, v); /* variable is local */ if (!base) { markupval(fs, v); /* local will be used as an upval */ } #ifdef LUA_UTILITIES_NET else { GetLocal(n, fs->ls); } #endif return VLOCAL; } else { /* not found as local at current level; try upvalues */ int idx = searchupvalue(fs, n); /* try existing upvalues */ if (idx < 0) { /* not found? */ if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ return VVOID; /* not found; is a global */ /* else was LOCAL or UPVAL */ idx = newupvalue(fs, n, var); /* will be a new upvalue */ } init_exp(var, VUPVAL, idx); #ifdef LUA_UTILITIES_NET GetUpvalue(n, fs->ls); #endif return VUPVAL; } } }
/* Find variable with given name 'n'. If it is an upvalue, add this upvalue into all intermediate functions. */ /*static*/ int FuncState::singlevaraux (/*FuncState *fs,*/ TString *n, expdesc *var, int base) { //if (fs == NULL) /* no more levels? */ //return VVOID; /* default is global */ //else { int v = searchvar(n); /* look up locals at current level */ if (v >= 0) { /* found? */ init_exp(var, VLOCAL, v); /* variable is local */ if (!base) markupval(v); /* local will be used as an upval */ return VLOCAL; } else { /* not found as local at current level; try upvalues */ int idx = searchupvalue(n); /* try existing upvalues */ if (idx < 0) { /* not found? */ if (prev->singlevaraux(n, var, 0) == VVOID) /* try upper levels */ return VVOID; /* not found; is a global */ /* else was LOCAL or UPVAL */ idx = newupvalue(n, var); /* will be a new upvalue */ } init_exp(var, VUPVAL, idx); return VUPVAL; } //} }
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars, BinOpr *opr) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); assignment(ls, &nv, nvars+1, opr); } else { /* assignment -> `=' explist1 */ int nexps; *opr = OPR_NOBINOPR; switch(ls->t.token) { case '=': break; case TK_CONCATASSIGN: *opr = OPR_CONCAT; break; case TK_ADDASSIGN: *opr = OPR_ADD; break; case TK_SUBASSIGN: *opr = OPR_SUB; break; case TK_MULASSIGN: *opr = OPR_MUL; break; case TK_DIVASSIGN: *opr = OPR_DIV; break; case TK_POWASSIGN: *opr = OPR_POW; break; case TK_MODASSIGN: *opr = OPR_MOD; break; default: luaX_syntaxerror(ls, "unexpected symbol"); break; }; luaX_next(ls); nexps = explist1(ls, &e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) ls->fs->freereg -= nexps - nvars; /* remove extra values */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e, *opr); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e, *opr); }
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' explist1 */ int nexps; /* hook for inc_assignment */ if(nvars==1) { switch(ls->t.token) { case '+': case '-': case '*': case '/': case TK_CONCAT: inc_assignment(ls,lh); /* If you're using Shook's table unpack patch, return 0 here.*/ return; } } checknext(ls, '='); nexps = explist1(ls, &e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) ls->fs->freereg -= nexps - nvars; /* remove extra values */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e); }
static void changevalue (LexState *ls, int op) { FuncState *fs = ls->fs; expdesc v, e1, e2; testnext(ls, '('); primaryexp(ls, &v); e1 = v; if (v.k == VINDEXED) luaK_reserveregs(fs, 1); /* <- this call solved the problem with indexed values */ if (testnext(ls, ',')) { luaK_exp2nextreg(fs, &e1); /* <- this call solved the problem with indexed values, 0.32.0 */ expr(ls, &e2); } else { /* using special opcodes is not faster */ init_exp(&e2, VKNUM, 0); e2.u.nval = (lua_Integer)1; } testnext(ls, ')'); codearith(fs, op, &e1, &e2); luaK_setoneret(fs, &e1); /* close last expression */ luaK_storevar(fs, &v, &e1); }
static void getfrom (LexState *ls, expdesc *e, expdesc *v) { expdesc key; int k = v->k; if (k == VLOCAL) { codestring(ls, &key, getlocvar(ls->fs, v->u.s.info).varname); } else if (k == VUPVAL) { codestring(ls, &key, ls->fs->f->upvalues[v->u.s.info]); } else if (k== VGLOBAL) { init_exp(&key, VK, v->u.s.info); } else { check_condition(ls, VLOCAL <= k && k <= VGLOBAL, "syntax error in from vars"); } luaK_indexed(ls->fs, e, &key); }
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' explist1 */ int nexps; #if LUA_MUTATION_OPERATORS luaX_next(ls); /* consume `=' token. */ #else checknext(ls, '='); #endif /* LUA_MUTATION_OPERATORS */ nexps = explist1(ls, &e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) ls->fs->freereg -= nexps - nvars; /* remove extra values */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e); }
static short decoder( short linewidth, unsigned char far * buf, unsigned char far * stack, unsigned char far * suffix, unsigned short far * prefix) { unsigned char far *sp; unsigned char far *bufptr; register short code, fc, oc, bufcnt; short c, size, ret; /* * Initialize for decoding a new image... */ if ((size = gif_get_byte()) < 0) return (size); if (size < 2 || 9 < size) return (BAD_CODE_SIZE); init_exp(size); /* * Initialize in case they forgot to put in a clear code. (This * shouldn't happen, but we'll try and decode it anyway...) */ oc = fc = 0; /* * Set up the stack pointer and decode buffer pointer */ sp = stack; bufptr = buf; bufcnt = linewidth; /* * This is the main loop. For each code we get we pass through the * linked list of prefix codes, pushing the corresponding "character" * for each code onto the stack. When the list reaches a single * "character" we push that on the stack too, and then start * unstacking each character for output in the correct order. Special * handling is included for the clear code, and the whole thing ends * when we get an ending code. */ while ((c = get_next_code()) != ending) { /* * If we had a file error, return without completing the * decode */ if (c < 0) { return (c); } /* * If the code is a clear code, reinitialize all necessary * items. */ if (c == clear) { curr_size = size + 1; slot = newcodes; top_slot = 1 << curr_size; /* * Continue reading codes until we get a non-clear * code (Another unlikely, but possible case...) */ while ((c = get_next_code()) == clear) ; /* * If we get an ending code immediately after a clear * code (Yet another unlikely case), then break out * of the loop. */ if (c == ending) break; /* * Finally, if the code is beyond the range of * already set codes, (This one had better NOT * happen... I have no idea what will result from * this, but I doubt it will look good...) then set * it to color zero. */ if (c >= slot) c = 0; oc = fc = c; /* * And let us not forget to put the char into the * buffer... And if, on the off chance, we were * exactly one pixel from the end of the line, we * have to send the buffer to the gif_out_line() * routine... */ *bufptr++ = c; if (--bufcnt == 0) { if ((ret = gif_out_line(buf, linewidth)) < 0) { return (ret); } bufptr = buf; bufcnt = linewidth; } } else { /* * In this case, it's not a clear code or an ending * code, so it must be a code code... So we can now * decode the code into a stack of character codes. * (Clear as mud, right?) */ code = c; /* * Here we go again with one of those off chances... * If, on the off chance, the code we got is beyond * the range of those already set up (Another thing * which had better NOT happen...) we trick the * decoder into thinking it actually got the last * code read. (Hmmn... I'm not sure why this works... * But it does...) */ if (code >= slot) { if (code > slot) ++bad_code_count; code = oc; *sp++ = fc; } /* * Here we scan back along the linked list of * prefixes, pushing helpless characters (ie. * suffixes) onto the stack as we do so. */ while (code >= newcodes) { *sp++ = suffix[code]; code = prefix[code]; } /* * Push the last character on the stack, and set up * the new prefix and suffix, and if the required * slot number is greater than that allowed by the * current bit size, increase the bit size. (NOTE - * If we are all full, we *don't* save the new suffix * and prefix... I'm not certain if this is * correct... it might be more proper to overwrite * the last code... */ *sp++ = code; if (slot < top_slot) { suffix[slot] = fc = code; prefix[slot++] = oc; oc = c; } if (slot >= top_slot) if (curr_size < 12) { top_slot <<= 1; ++curr_size; } /* * Now that we've pushed the decoded string (in * reverse order) onto the stack, lets pop it off and * put it into our decode buffer... And when the * decode buffer is full, write another line... */ while (sp > stack) { *bufptr++ = *(--sp); if (--bufcnt == 0) { if ((ret = gif_out_line(buf, linewidth)) < 0) { return (ret); } bufptr = buf; bufcnt = linewidth; } } } } ret = 0; if (bufcnt != linewidth) ret = gif_out_line(buf, (linewidth - bufcnt)); return (ret); }
double PmeKSpace::compute_energy(float *q_arr, const Lattice &lattice, double ewald, double *virial) { double energy = 0.0; double v0 = 0.; double v1 = 0.; double v2 = 0.; double v3 = 0.; double v4 = 0.; double v5 = 0.; int n; int k1, k2, k3, ind; int K1, K2, K3; K1=myGrid.K1; K2=myGrid.K2; K3=myGrid.K3; i_pi_volume = 1.0/(M_PI * lattice.volume()); piob = M_PI/ewald; piob *= piob; if ( lattice.orthogonal() ) { // if ( 0 ) { // JCP FOR TESTING //This branch is the usual call path. #if USE_CKLOOP int useCkLoop = Node::Object()->simParameters->useCkLoop; if(useCkLoop>=CKLOOP_CTRL_PME_KSPACE){ return compute_energy_orthogonal_helper(q_arr, lattice, ewald, virial); } #endif double recipx = lattice.a_r().x; double recipy = lattice.b_r().y; double recipz = lattice.c_r().z; init_exp(exp1, K1, 0, K1, recipx); init_exp(exp2, K2, k2_start, k2_end, recipy); init_exp(exp3, K3, k3_start, k3_end, recipz); ind = 0; for ( k1=0; k1<K1; ++k1 ) { double m1, m11, b1, xp1; b1 = bm1[k1]; int k1_s = k1<=K1/2 ? k1 : k1-K1; m1 = k1_s*recipx; m11 = m1*m1; xp1 = i_pi_volume*exp1[abs(k1_s)]; for ( k2=k2_start; k2<k2_end; ++k2 ) { double m2, m22, b1b2, xp2; b1b2 = b1*bm2[k2]; int k2_s = k2<=K2/2 ? k2 : k2-K2; m2 = k2_s*recipy; m22 = m2*m2; xp2 = exp2[abs(k2_s)]*xp1; k3 = k3_start; if ( k1==0 && k2==0 && k3==0 ) { q_arr[ind++] = 0.0; q_arr[ind++] = 0.0; ++k3; } for ( ; k3<k3_end; ++k3 ) { double m3, m33, xp3, msq, imsq, vir, fac; double theta3, theta, q2, qr, qc, C; theta3 = bm3[k3] *b1b2; m3 = k3*recipz; m33 = m3*m3; xp3 = exp3[k3]; qr = q_arr[ind]; qc=q_arr[ind+1]; q2 = 2*(qr*qr + qc*qc)*theta3; if ( (k3 == 0) || ( k3 == K3/2 && ! (K3 & 1) ) ) q2 *= 0.5; msq = m11 + m22 + m33; imsq = 1.0/msq; C = xp2*xp3*imsq; theta = theta3*C; q_arr[ind] *= theta; q_arr[ind+1] *= theta; vir = -2*(piob+imsq); fac = q2*C; energy += fac; v0 += fac*(1.0+vir*m11); v1 += fac*vir*m1*m2; v2 += fac*vir*m1*m3; v3 += fac*(1.0+vir*m22); v4 += fac*vir*m2*m3; v5 += fac*(1.0+vir*m33); ind += 2; } } } } else if ( cross(lattice.a(),lattice.b()).unit() == lattice.c().unit() ) { // } else if ( 0 ) { // JCP FOR TESTING Vector recip1 = lattice.a_r(); Vector recip2 = lattice.b_r(); Vector recip3 = lattice.c_r(); double recip3_x = recip3.x; double recip3_y = recip3.y; double recip3_z = recip3.z; init_exp(exp3, K3, k3_start, k3_end, recip3.length()); ind = 0; for ( k1=0; k1<K1; ++k1 ) { double b1; Vector m1; b1 = bm1[k1]; int k1_s = k1<=K1/2 ? k1 : k1-K1; m1 = k1_s*recip1; // xp1 = i_pi_volume*exp1[abs(k1_s)]; for ( k2=k2_start; k2<k2_end; ++k2 ) { double xp2, b1b2, m2_x, m2_y, m2_z; b1b2 = b1*bm2[k2]; int k2_s = k2<=K2/2 ? k2 : k2-K2; m2_x = m1.x + k2_s*recip2.x; m2_y = m1.y + k2_s*recip2.y; m2_z = m1.z + k2_s*recip2.z; // xp2 = exp2[abs(k2_s)]*xp1; xp2 = i_pi_volume*exp(-piob*(m2_x*m2_x+m2_y*m2_y+m2_z*m2_z)); k3 = k3_start; if ( k1==0 && k2==0 && k3==0 ) { q_arr[ind++] = 0.0; q_arr[ind++] = 0.0; ++k3; } for ( ; k3<k3_end; ++k3 ) { double xp3, msq, imsq, vir, fac; double theta3, theta, q2, qr, qc, C; double m_x, m_y, m_z; theta3 = bm3[k3] *b1b2; m_x = m2_x + k3*recip3_x; m_y = m2_y + k3*recip3_y; m_z = m2_z + k3*recip3_z; msq = m_x*m_x + m_y*m_y + m_z*m_z; xp3 = exp3[k3]; qr = q_arr[ind]; qc=q_arr[ind+1]; q2 = 2*(qr*qr + qc*qc)*theta3; if ( (k3 == 0) || ( k3 == K3/2 && ! (K3 & 1) ) ) q2 *= 0.5; imsq = 1.0/msq; C = xp2*xp3*imsq; theta = theta3*C; q_arr[ind] *= theta; q_arr[ind+1] *= theta; vir = -2*(piob+imsq); fac = q2*C; energy += fac; v0 += fac*(1.0+vir*m_x*m_x); v1 += fac*vir*m_x*m_y; v2 += fac*vir*m_x*m_z; v3 += fac*(1.0+vir*m_y*m_y); v4 += fac*vir*m_y*m_z; v5 += fac*(1.0+vir*m_z*m_z); ind += 2; } } } } else { Vector recip1 = lattice.a_r(); Vector recip2 = lattice.b_r(); Vector recip3 = lattice.c_r(); double recip3_x = recip3.x; double recip3_y = recip3.y; double recip3_z = recip3.z; ind = 0; for ( k1=0; k1<K1; ++k1 ) { double b1; Vector m1; b1 = bm1[k1]; int k1_s = k1<=K1/2 ? k1 : k1-K1; m1 = k1_s*recip1; // xp1 = i_pi_volume*exp1[abs(k1_s)]; for ( k2=k2_start; k2<k2_end; ++k2 ) { double b1b2, m2_x, m2_y, m2_z; b1b2 = b1*bm2[k2]; int k2_s = k2<=K2/2 ? k2 : k2-K2; m2_x = m1.x + k2_s*recip2.x; m2_y = m1.y + k2_s*recip2.y; m2_z = m1.z + k2_s*recip2.z; // xp2 = exp2[abs(k2_s)]*xp1; k3 = k3_start; if ( k1==0 && k2==0 && k3==0 ) { q_arr[ind++] = 0.0; q_arr[ind++] = 0.0; ++k3; } for ( ; k3<k3_end; ++k3 ) { double xp3, msq, imsq, vir, fac; double theta3, theta, q2, qr, qc, C; double m_x, m_y, m_z; theta3 = bm3[k3] *b1b2; m_x = m2_x + k3*recip3_x; m_y = m2_y + k3*recip3_y; m_z = m2_z + k3*recip3_z; msq = m_x*m_x + m_y*m_y + m_z*m_z; // xp3 = exp3[k3]; xp3 = i_pi_volume*exp(-piob*msq); qr = q_arr[ind]; qc=q_arr[ind+1]; q2 = 2*(qr*qr + qc*qc)*theta3; if ( (k3 == 0) || ( k3 == K3/2 && ! (K3 & 1) ) ) q2 *= 0.5; imsq = 1.0/msq; C = xp3*imsq; theta = theta3*C; q_arr[ind] *= theta; q_arr[ind+1] *= theta; vir = -2*(piob+imsq); fac = q2*C; energy += fac; v0 += fac*(1.0+vir*m_x*m_x); v1 += fac*vir*m_x*m_y; v2 += fac*vir*m_x*m_z; v3 += fac*(1.0+vir*m_y*m_y); v4 += fac*vir*m_y*m_z; v5 += fac*(1.0+vir*m_z*m_z); ind += 2; } } } } virial[0] = 0.5 * v0; virial[1] = 0.5 * v1; virial[2] = 0.5 * v2; virial[3] = 0.5 * v3; virial[4] = 0.5 * v4; virial[5] = 0.5 * v5; return 0.5*energy; }
static void primaryexp (LexState *ls, expdesc *v) { /* primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ FuncState *fs = ls->fs; prefixexp(ls, v); for (;;) { switch (ls->t.token) { case '.': { /* field */ field(ls, v); break; } case '[': { /* `[' exp1 `]' */ expdesc key; luaK_exp2anyreg(fs, v); yindex(ls, &key); luaK_indexed(fs, v, &key); break; } case ':': { /* `:' NAME funcargs */ expdesc key; luaX_next(ls); checkname(ls, &key); luaK_self(fs, v, &key); funcargs(ls, v); break; } #if LUA_WIDESTRING case '(': case TK_STRING: case TK_WSTRING: case '{': { /* funcargs */ #else case '(': case TK_STRING: case '{': { /* funcargs */ #endif /* LUA_WIDESTRING */ luaK_exp2nextreg(fs, v); funcargs(ls, v); break; } default: return; } } } static void simpleexp (LexState *ls, expdesc *v) { #if LUA_WIDESTRING /* simpleexp -> NUMBER | STRING | WSTRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp */ #else /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp */ #endif /* LUA_WIDESTRING */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VKNUM, 0); v->u.nval = ls->t.seminfo.r; break; } case TK_STRING: { codestring(ls, v, ls->t.seminfo.ts); break; } #if LUA_WIDESTRING case TK_WSTRING: { codewstring(ls, v, ls->t.seminfo.ts); break; } #endif /* LUA_WIDESTRING */ case TK_NIL: { init_exp(v, VNIL, 0); break; } case TK_TRUE: { init_exp(v, VTRUE, 0); break; } case TK_FALSE: { init_exp(v, VFALSE, 0); break; } case TK_DOTS: { /* vararg */ FuncState *fs = ls->fs; check_condition(ls, fs->f->is_vararg, "cannot use " LUA_QL("...") " outside a vararg function"); fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } case '{': { /* constructor */ constructor(ls, v); return; } case TK_FUNCTION: { luaX_next(ls); body(ls, v, 0, ls->linenumber); return; } default: { primaryexp(ls, v); return; } } luaX_next(ls); } static UnOpr getunopr (int op) { switch (op) { case TK_NOT: return OPR_NOT; case '-': return OPR_MINUS; case '#': return OPR_LEN; default: return OPR_NOUNOPR; } } static BinOpr getbinopr (int op) { switch (op) { case '+': return OPR_ADD; case '-': return OPR_SUB; case '*': return OPR_MUL; case '/': return OPR_DIV; case '%': return OPR_MOD; #if LUA_BITFIELD_OPS case '&': return OPR_BAND; case '|': return OPR_BOR; case TK_XOR: return OPR_BXOR; case TK_SHL: return OPR_BSHL; case TK_SHR: return OPR_BSHR; #endif /* LUA_BITFIELD_OPS */ case '^': return OPR_POW; case TK_CONCAT: return OPR_CONCAT; case TK_NE: return OPR_NE; case TK_EQ: return OPR_EQ; case '<': return OPR_LT; case TK_LE: return OPR_LE; case '>': return OPR_GT; case TK_GE: return OPR_GE; case TK_AND: return OPR_AND; case TK_OR: return OPR_OR; default: return OPR_NOBINOPR; } } static const struct { lu_byte left; /* left priority for each binary operator */ lu_byte right; /* right priority */ } priority[] = { /* ORDER OPR */ #if LUA_BITFIELD_OPS {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, /* bitwise operators */ #endif /* LUA_BITFIELD_OPS */ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ {10, 9}, {5, 4}, /* power and concat (right associative) */ {3, 3}, {3, 3}, /* equality and inequality */ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ {2, 2}, {1, 1} /* logical (and/or) */ }; #define UNARY_PRIORITY 8 /* priority for unary operators */ /* ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } ** where `binop' is any binary operator with a priority higher than `limit' */ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { BinOpr op; UnOpr uop; enterlevel(ls); uop = getunopr(ls->t.token); if (uop != OPR_NOUNOPR) { luaX_next(ls); subexpr(ls, v, UNARY_PRIORITY); luaK_prefix(ls->fs, uop, v); } else simpleexp(ls, v); /* expand while operators have priorities higher than `limit' */ op = getbinopr(ls->t.token); while (op != OPR_NOBINOPR && priority[op].left > limit) { expdesc v2; BinOpr nextop; luaX_next(ls); luaK_infix(ls->fs, op, v); /* read sub-expression with higher priority */ nextop = subexpr(ls, &v2, priority[op].right); luaK_posfix(ls->fs, op, v, &v2); op = nextop; } leavelevel(ls); return op; /* return first untreated operator */ }
static void codestring (LexState *ls, expdesc *e, TString *s) { init_exp(e, VK, luaK_stringK(ls->fs, s)); }
static void codestring(ktap_lexstate *ls, ktap_expdesc *e, ktap_string *s) { init_exp(e, VK, codegen_stringK(ls->fs, s)); }
double PmeKSpace::compute_energy_orthogonal_helper(float *q_arr, const Lattice &lattice, double ewald, double *virial) { double energy = 0.0; double v0 = 0.; double v1 = 0.; double v2 = 0.; double v3 = 0.; double v4 = 0.; double v5 = 0.; int n; int k1, k2, k3, ind; int K1, K2, K3; K1=myGrid.K1; K2=myGrid.K2; K3=myGrid.K3; i_pi_volume = 1.0/(M_PI * lattice.volume()); piob = M_PI/ewald; piob *= piob; double recipx = lattice.a_r().x; double recipy = lattice.b_r().y; double recipz = lattice.c_r().z; init_exp(exp1, K1, 0, K1, recipx); init_exp(exp2, K2, k2_start, k2_end, recipy); init_exp(exp3, K3, k3_start, k3_end, recipz); double recips[] = {recipx, recipy, recipz}; const int NPARTS=CmiMyNodeSize(); //this controls the granularity of loop parallelism ALLOCA(double, partialEnergy, NPARTS); ALLOCA(double, partialVirial, 6*NPARTS); int unitDist[] = {K1/NPARTS, K1%NPARTS}; //parallelize the following loop using CkLoop void *params[] = {this, q_arr, recips, partialEnergy, partialVirial, unitDist}; #if USE_CKLOOP CProxy_FuncCkLoop ckLoop = CkpvAccess(BOCclass_group).ckLoop; CkLoop_Parallelize(ckLoop, compute_energy_orthogonal_ckloop, 6, (void *)params, NPARTS, 0, NPARTS-1); #endif /* //The transformed loop used to compute energy int unit = K1/NPARTS; int remains = K1%NPARTS; for(int i=0; i<NPARTS; i++){ int k1from, k1to; if(i<remains){ k1from = i*(unit+1); k1to = k1from+unit; }else{ k1from = remains*(unit+1)+(i-remains)*unit; k1to = k1from+unit-1; } double *pEnergy = partialEnergy+i; double *pVirial = partialVirial+i*6; compute_energy_orthogonal_subset(q_arr, recips, pVirial, pEnergy, k1from, k1to); } */ for(int i=0; i<NPARTS; i++){ v0 += partialVirial[i*6+0]; v1 += partialVirial[i*6+1]; v2 += partialVirial[i*6+2]; v3 += partialVirial[i*6+3]; v4 += partialVirial[i*6+4]; v5 += partialVirial[i*6+5]; energy += partialEnergy[i]; } virial[0] = v0; virial[1] = v1; virial[2] = v2; virial[3] = v3; virial[4] = v4; virial[5] = v5; return energy; }
static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], int total_gain) { int v, bsize, ch, coef_nb_bits, parse_exponents; float mdct_norm; int nb_coefs[MAX_CHANNELS]; static const int fixed_exp[25] = { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }; // FIXME remove duplication relative to decoder if (s->use_variable_block_len) { av_assert0(0); // FIXME not implemented } else { /* fixed block len */ s->next_block_len_bits = s->frame_len_bits; s->prev_block_len_bits = s->frame_len_bits; s->block_len_bits = s->frame_len_bits; } s->block_len = 1 << s->block_len_bits; // av_assert0((s->block_pos + s->block_len) <= s->frame_len); bsize = s->frame_len_bits - s->block_len_bits; // FIXME factor v = s->coefs_end[bsize] - s->coefs_start; for (ch = 0; ch < s->avctx->channels; ch++) nb_coefs[ch] = v; { int n4 = s->block_len / 2; mdct_norm = 1.0 / (float) n4; if (s->version == 1) mdct_norm *= sqrt(n4); } if (s->avctx->channels == 2) put_bits(&s->pb, 1, !!s->ms_stereo); for (ch = 0; ch < s->avctx->channels; ch++) { // FIXME only set channel_coded when needed, instead of always s->channel_coded[ch] = 1; if (s->channel_coded[ch]) init_exp(s, ch, fixed_exp); } for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { WMACoef *coefs1; float *coefs, *exponents, mult; int i, n; coefs1 = s->coefs1[ch]; exponents = s->exponents[ch]; mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; mult *= mdct_norm; coefs = src_coefs[ch]; if (s->use_noise_coding && 0) { av_assert0(0); // FIXME not implemented } else { coefs += s->coefs_start; n = nb_coefs[ch]; for (i = 0; i < n; i++) { double t = *coefs++ / (exponents[i] * mult); if (t < -32768 || t > 32767) return -1; coefs1[i] = lrint(t); } } } } v = 0; for (ch = 0; ch < s->avctx->channels; ch++) { int a = s->channel_coded[ch]; put_bits(&s->pb, 1, a); v |= a; } if (!v) return 1; for (v = total_gain - 1; v >= 127; v -= 127) put_bits(&s->pb, 7, 127); put_bits(&s->pb, 7, v); coef_nb_bits = ff_wma_total_gain_to_bits(total_gain); if (s->use_noise_coding) { for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { int i, n; n = s->exponent_high_sizes[bsize]; for (i = 0; i < n; i++) { put_bits(&s->pb, 1, s->high_band_coded[ch][i] = 0); if (0) nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; } } } } parse_exponents = 1; if (s->block_len_bits != s->frame_len_bits) put_bits(&s->pb, 1, parse_exponents); if (parse_exponents) { for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { if (s->use_exp_vlc) { encode_exp_vlc(s, ch, fixed_exp); } else { av_assert0(0); // FIXME not implemented // encode_exp_lsp(s, ch); } } } } else av_assert0(0); // FIXME not implemented for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { int run, tindex; WMACoef *ptr, *eptr; tindex = (ch == 1 && s->ms_stereo); ptr = &s->coefs1[ch][0]; eptr = ptr + nb_coefs[ch]; run = 0; for (; ptr < eptr; ptr++) { if (*ptr) { int level = *ptr; int abs_level = FFABS(level); int code = 0; if (abs_level <= s->coef_vlcs[tindex]->max_level) if (run < s->coef_vlcs[tindex]->levels[abs_level - 1]) code = run + s->int_table[tindex][abs_level - 1]; av_assert2(code < s->coef_vlcs[tindex]->n); put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[code], s->coef_vlcs[tindex]->huffcodes[code]); if (code == 0) { if (1 << coef_nb_bits <= abs_level) return -1; put_bits(&s->pb, coef_nb_bits, abs_level); put_bits(&s->pb, s->frame_len_bits, run); } // FIXME the sign is flipped somewhere put_bits(&s->pb, 1, level < 0); run = 0; } else run++; } if (run) put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[1], s->coef_vlcs[tindex]->huffcodes[1]); } if (s->version == 1 && s->avctx->channels >= 2) avpriv_align_put_bits(&s->pb); } return 0; }
static void constructor (LexState *ls, expdesc *t) { /* constructor -> ?? */ FuncState *fs = ls->fs; int line = ls->linenumber; int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); struct ConsControl cc; cc.na = cc.nh = cc.tostore = 0; cc.t = t; init_exp(t, VRELOCABLE, pc); init_exp(&cc.v, VVOID, 0); /* no value (yet) */ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ checknext(ls, '{'); #if LUA_OPTIONAL_COMMA for (;;) { #else do { #endif /* LUA_OPTIONAL_COMMA */ lua_assert(cc.v.k == VVOID || cc.tostore > 0); if (ls->t.token == '}') break; closelistfield(fs, &cc); switch(ls->t.token) { case TK_NAME: { /* may be listfields or recfields */ luaX_lookahead(ls); if (ls->lookahead.token != '=') /* expression? */ listfield(ls, &cc); else recfield(ls, &cc); break; } case '[': { /* constructor_item -> recfield */ recfield(ls, &cc); break; } default: { /* constructor_part -> listfield */ listfield(ls, &cc); break; } } #if LUA_OPTIONAL_COMMA if (ls->t.token == ',' || ls->t.token == ';') next(ls); else if (ls->t.token == '}') break; } #else } while (testnext(ls, ',') || testnext(ls, ';')); #endif /* LUA_OPTIONAL_COMMA */ check_match(ls, '}', '{', line); lastlistfield(fs, &cc); SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ } /* }====================================================================== */ static void parlist (LexState *ls) { /* parlist -> [ param { `,' param } ] */ FuncState *fs = ls->fs; Proto *f = fs->f; int nparams = 0; f->is_vararg = 0; if (ls->t.token != ')') { /* is `parlist' not empty? */ do { switch (ls->t.token) { case TK_NAME: { /* param -> NAME */ new_localvar(ls, str_checkname(ls), nparams++); break; } case TK_DOTS: { /* param -> `...' */ luaX_next(ls); #if defined(LUA_COMPAT_VARARG) /* use `arg' as default name */ new_localvarliteral(ls, "arg", nparams++); f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; #endif f->is_vararg |= VARARG_ISVARARG; break; } default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); } } while (!f->is_vararg && testnext(ls, ',')); } adjustlocalvars(ls, nparams); f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ }