static int luaV_list_index (lua_State *L) { list_T *l = luaV_unbox(L, luaV_List, 1); if (lua_isnumber(L, 2)) /* list item? */ { listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2)); if (li == NULL) lua_pushnil(L); else luaV_pushtypval(L, &li->li_tv); } else if (lua_isstring(L, 2)) /* method? */ { const char *s = lua_tostring(L, 2); if (strncmp(s, "add", 3) == 0 || strncmp(s, "insert", 6) == 0) { lua_getmetatable(L, 1); lua_getfield(L, -1, s); } else lua_pushnil(L); } else lua_pushnil(L); return 1; }
static int luaV_eval(lua_State *L) { typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL); if (tv == NULL) luaL_error(L, "invalid expression"); luaV_pushtypval(L, tv); return 1; }
static int luaV_list_iter (lua_State *L) { listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2)); if (li == NULL) return 0; luaV_pushtypval(L, &li->li_tv); lua_pushlightuserdata(L, (void *) li->li_next); lua_replace(L, lua_upvalueindex(2)); return 1; }
static int luaV_dict_index (lua_State *L) { dict_T *d = luaV_unbox(L, luaV_Dict, 1); char_u *key = (char_u *) luaL_checkstring(L, 2); dictitem_T *di = dict_find(d, key, -1); if (di == NULL) lua_pushnil(L); else luaV_pushtypval(L, &di->di_tv); return 1; }
static int luaV_dict_iter (lua_State *L) { hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2)); int n = lua_tointeger(L, lua_upvalueindex(3)); dictitem_T *di; if (n <= 0) return 0; while (HASHITEM_EMPTY(hi)) hi++; di = dict_lookup(hi); lua_pushstring(L, (char *) hi->hi_key); luaV_pushtypval(L, &di->di_tv); lua_pushlightuserdata(L, (void *) (hi + 1)); lua_replace(L, lua_upvalueindex(2)); lua_pushinteger(L, n - 1); lua_replace(L, lua_upvalueindex(3)); return 2; }
static void luaV_pushtypval(lua_State *L, typval_T *tv) { if (tv == NULL) luaL_error(L, "null type"); switch (tv->v_type) { case VAR_STRING: lua_pushstring(L, (char *) tv->vval.v_string); break; case VAR_NUMBER: lua_pushinteger(L, (int) tv->vval.v_number); break; #ifdef FEAT_FLOAT case VAR_FLOAT: lua_pushnumber(L, (lua_Number) tv->vval.v_float); break; #endif case VAR_LIST: { list_T *l = tv->vval.v_list; if (l != NULL) { /* check cache */ lua_pushlightuserdata(L, (void *) l); lua_rawget(L, LUA_ENVIRONINDEX); if (lua_isnil(L, -1)) /* not interned? */ { listitem_T *li; int n = 0; lua_pop(L, 1); /* nil */ lua_newtable(L); lua_pushlightuserdata(L, (void *) l); lua_pushvalue(L, -2); lua_rawset(L, LUA_ENVIRONINDEX); for (li = l->lv_first; li != NULL; li = li->li_next) { luaV_pushtypval(L, &li->li_tv); lua_rawseti(L, -2, ++n); } } } else lua_pushnil(L); break; } case VAR_DICT: { dict_T *d = tv->vval.v_dict; if (d != NULL) { /* check cache */ lua_pushlightuserdata(L, (void *) d); lua_rawget(L, LUA_ENVIRONINDEX); if (lua_isnil(L, -1)) /* not interned? */ { hashtab_T *ht = &d->dv_hashtab; hashitem_T *hi; int n = ht->ht_used; /* remaining items */ lua_pop(L, 1); /* nil */ lua_newtable(L); lua_pushlightuserdata(L, (void *) d); lua_pushvalue(L, -2); lua_rawset(L, LUA_ENVIRONINDEX); for (hi = ht->ht_array; n > 0; hi++) { if (!HASHITEM_EMPTY(hi)) { dictitem_T *di = dict_lookup(hi); luaV_pushtypval(L, &di->di_tv); lua_setfield(L, -2, (char *) hi->hi_key); n--; } } } } else lua_pushnil(L); break; } default: luaL_error(L, "invalid type"); } }