diff --git a/limmutable.c b/limmutable.c index deff4c0..ed3caa4 100644 --- a/limmutable.c +++ b/limmutable.c @@ -252,11 +252,18 @@ static int Ltostring(lua_State *L) } else { needs_comma = 1; } + // Stack: [mt, buckets, bucket, inst_table, fields, i, fieldname] + lua_getglobal(L, "tostring"); + lua_insert(L, -2); + lua_call(L, 1, 1); luaL_addvalue(&b); // Stack: [mt, buckets, bucket, inst_table, fields, i] luaL_addstring(&b, "="); lua_rawgeti(L, -3, lua_tonumber(L, -1)); // Stack: [mt, buckets, bucket, inst_table, fields, i, value] + lua_getglobal(L, "tostring"); + lua_insert(L, -2); + lua_call(L, 1, 1); luaL_addvalue(&b); // Stack: [mt, buckets, bucket, inst_table, fields, i] } @@ -265,10 +272,47 @@ static int Ltostring(lua_State *L) return 1; } +static int Lnexti(lua_State *L) +{ + lua_getmetatable(L, 1); + // Stack: [mt] + lua_getfield(L, -1, "__instances"); + // Stack: [mt, buckets] + lua_rawgeti(L, -1, *((lua_Integer*)lua_touserdata(L, 1))); + // Stack: [mt, buckets, bucket] + lua_pushvalue(L, 1); + // Stack: [mt, buckets, bucket, inst_udata] + lua_rawget(L, -2); + // Stack: [mt, buckets, bucket, inst_table] + lua_getfield(L, -4, "__fields"); + // Stack: [mt, buckets, bucket, inst_table, fields] + lua_pushvalue(L, 2); + // Stack: [mt, buckets, bucket, inst_table, fields, i] + if (lua_next(L, -2) == 0) { + return 0; + } + // Stack: [mt, buckets, bucket, inst_table, fields, i2, next_fieldname] + lua_rawgeti(L, -4, lua_tonumber(L, -2)); + // Stack: [mt, buckets, bucket, inst_table, fields, i2, next_fieldname, value] + return 3; +} + +static int Lipairs(lua_State *L) +{ + lua_pushcfunction(L, Lnexti); + // Stack: [Lnexti] + lua_pushvalue(L, 1); + // Stack: [Lnexti, inst_udata] + lua_pushnil(L); + // Stack: [Lnexti, inst_udata, nil] + return 3; +} + static const luaL_Reg R[] = { { "__len", Llen}, { "__index", Lindex}, + { "__ipairs", Lipairs}, { "new", Lcreate_instance}, { NULL, NULL} };