| 4886 | |
| 4887 | |
| 4888 | static void enumstat (LexState *ls) { |
| 4889 | /* enumstat -> ENUM [[CLASS] NAME] BEGIN NAME ['=' INT] { ',' NAME ['=' INT] } END */ |
| 4890 | |
| 4891 | luaX_next(ls); /* skip 'enum' */ |
| 4892 | |
| 4893 | EnumDesc *ed = nullptr; |
| 4894 | bool is_enum_class = false; |
| 4895 | if (gett(ls) != TK_BEGIN && gett(ls) != TK_DO) { /* enum has name (and possibly modifier)? */ |
| 4896 | if (ls->t.token == TK_CLASS |
| 4897 | || (ls->t.token == TK_NAME && strcmp(getstr(ls->t.seminfo.ts), "class") == 0) |
| 4898 | ) { |
| 4899 | is_enum_class = true; |
| 4900 | luaX_next(ls); |
| 4901 | } |
| 4902 | auto vidx = new_localvar(ls, str_checkname(ls, 0), ls->getLineNumber()); |
| 4903 | auto var = getlocalvardesc(ls->fs, vidx); |
| 4904 | var->vd.kind = RDKENUM; |
| 4905 | setivalue(&var->k, ls->enums.size()); |
| 4906 | ed = &ls->enums.emplace_back(EnumDesc{}); |
| 4907 | ls->fs->nactvar++; |
| 4908 | } |
| 4909 | |
| 4910 | const auto line_begin = ls->getLineNumber(); |
| 4911 | if (!testnext(ls, TK_DO)) |
| 4912 | checknext(ls, TK_BEGIN); |
| 4913 | |
| 4914 | lua_Integer i = 1; |
| 4915 | while (gett(ls) != TK_END) { |
| 4916 | TString *name = str_checkname(ls, 0); |
| 4917 | int vidx; |
| 4918 | if (!is_enum_class) { |
| 4919 | vidx = new_localvar(ls, name, ls->getLineNumber()); |
| 4920 | } |
| 4921 | if (testnext(ls, '=')) { |
| 4922 | expdesc v; |
| 4923 | expr(ls, &v); |
| 4924 | if (v.k == VCONST) { /* compile-time constant? */ |
| 4925 | TValue *k = &ls->dyd->actvar.arr[v.u.info].k; |
| 4926 | if (ttype(k) == LUA_TNUMBER && ttisinteger(k)) { /* integer value? */ |
| 4927 | init_exp(&v, VKINT, 0); |
| 4928 | v.u.ival = ivalue(k); |
| 4929 | } |
| 4930 | } |
| 4931 | if (v.k != VKINT) { /* assert expdesc kind */ |
| 4932 | throwerr(ls, "expected integer constant", "unexpected expression type"); |
| 4933 | } |
| 4934 | i = v.u.ival; |
| 4935 | } |
| 4936 | if (ed) { |
| 4937 | ed->enumerators.emplace_back(EnumDesc::Enumerator{ name, i }); |
| 4938 | } |
| 4939 | if (!is_enum_class) { |
| 4940 | auto var = getlocalvardesc(ls->fs, vidx); |
| 4941 | var->vd.kind = RDKCTC; |
| 4942 | setivalue(&var->k, i); |
| 4943 | ls->fs->nactvar++; |
| 4944 | } |
| 4945 | i++; |
no test coverage detected