lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 1-Sep-05, at 12:19 PM, Mark Hamburg wrote:

That implementation is unfriendly toward nil's in ... isn't it?

True. For the simple case, rather than use a sentinel,
we could just put the count in the otherwise unused argument:

// insert at line 248
static int ieachaux (lua_State *L) {
  int n = luaL_checkint(L, 1);  /* added */
  int i = luaL_checkint(L, 2);
  if (i <= n) {
    i++;
    lua_pushinteger(L, i);
    lua_pushvalue(lua_upvalueindex(i));
    return 2;
  }
  else
    return 0;
}

// But for the table case, we need to use a sentinel, which might as well
// be the table itself.

static int ieachaux_table (lua_State *L) {
  int i = luaL_checkint(L, 2);
  luaL_checktype(L, 1, LUA_TABLE);
  i++;
  lua_pushinteger(L, i);
  lua_rawgeti(L, 1, i);
  if (lua_rawequal(L, 1, -1)) {
    lua_pop(L, 1);
    return 1;
  }
  else return lua_isnil(L, -1) ? 0 : 2;
}


static int luaB_ieach (lua_State *L) {
  int n = lua_gettop(L);
  if (n <= LUAI_MAXUPVALUES) {
    lua_pushcclosure(L, ieachaux, n);
    lua_pushinteger(L, n);  /* Changed */
  }
  else {
    lua_pushvalue(L, lua_upvalueindex(1));
    lua_createtable(L, n, 0);
    do {
      if (lua_isnil(L, n)      /* added */
        lua_pushvalue(L, -1);
      else
        lua_pushvalue(L, n);   /* corrected */
      lua_rawseti(L, -2, n);   /* corrected */
    } while (--n);
  }
  lua_pushinteger(L, 0);
  return 3;
}


// insert in base_open, line 623:
  auxopen(L, "ieach", luaB_ieach, ieachaux_table);  /* Changed */

Moral: more eyes, fewer bugs.
Also: Don't type C into an email message :)

Hope I got it closer to right this time.