github.com/aergoio/aergo@v1.3.1/cmd/aergoluac/util/state_module.c (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  #include <stdint.h>
     7  #include <string.h>
     8  #include <lualib.h>
     9  #include <lauxlib.h>
    10  #include <luajit.h>
    11  
    12  #define TYPE_NAME "_type_"
    13  #define TYPE_LEN  "_len_"
    14  #define TYPE_DIMENSION  "_dimension_"
    15  
    16  #define STATE_MAX_DIMENSION 5
    17  
    18  static int state_map(lua_State *L)
    19  {
    20      int dimension = 1;
    21  
    22      if (luaL_isinteger(L, 1))
    23          dimension = luaL_checkint(L, 1);       /* m _type_ map dim*/
    24      else if (lua_gettop(L) != 0)
    25          luaL_typerror(L, 1, "integer");
    26  
    27      if (dimension > STATE_MAX_DIMENSION) {
    28          luaL_error(L, "dimension over max limit(%d): %d, state.map",
    29                     STATE_MAX_DIMENSION, dimension);
    30      }
    31      lua_newtable(L);
    32      lua_pushstring(L, TYPE_NAME);   /* m _type_ */
    33      lua_pushstring(L, "map");       /* m _type_ map */
    34      lua_rawset(L, -3);
    35      lua_pushstring(L, TYPE_DIMENSION);       /* m _dimension_ */
    36      lua_pushinteger(L, dimension);       /* m _type_ map dim*/
    37      lua_rawset(L, -3);
    38      return 1;
    39  }
    40  
    41  static int state_array(lua_State *L)
    42  {
    43      int32_t len = 0;
    44      int argn = lua_gettop(L);
    45  
    46      if (argn > STATE_MAX_DIMENSION) {
    47          luaL_error(L, "dimension over max limit(%d): %d, state.array",
    48                     STATE_MAX_DIMENSION, argn);
    49      }
    50      lua_newtable(L);
    51      lua_pushstring(L, TYPE_NAME);   /* m _type_ */
    52      lua_pushstring(L, "array");     /* m _type_ array */
    53      lua_rawset(L, -3);
    54      lua_pushstring(L, TYPE_LEN);    /* m _len_ */
    55      if (argn == 0) {
    56          lua_pushinteger(L, len);        /* m _len_ len*/
    57      } else if (argn == 1) {
    58          if (!luaL_isinteger(L, 1)) {
    59              luaL_typerror(L, 1, "integer");
    60          }
    61          len = luaL_checkint(L, 1);      /* size */
    62          luaL_argcheck(L, (len > 0), 1, "the array length must be greater than zero");
    63          lua_pushinteger(L, len);        /* m _len_ len*/
    64      } else {
    65          int i;
    66          lua_pushstring(L, TYPE_DIMENSION);   /* m _len_ _dimension_ */
    67          for (i = 1; i <= argn; ++i) {
    68              if (!luaL_isinteger(L, i)) {
    69                  luaL_typerror(L, i, "integer");
    70              }
    71              len = luaL_checkint(L, i);      /* size */
    72              luaL_argcheck(L, (len > 0), 1, "the array length must be greater than zero");
    73              lua_pushinteger(L, len);
    74              lua_pushstring(L, ",");
    75          }
    76          lua_pop(L, 1);
    77          lua_concat(L, argn * 2 - 1);
    78          lua_rawset(L, -4);      /* m _len_ */
    79          lua_pushinteger(L, 0);  /* m _len_ len*/
    80      }
    81      lua_rawset(L, -3);
    82      return 1;
    83  }
    84  
    85  static int state_value(lua_State *L)
    86  {
    87      lua_newtable(L);
    88      lua_pushstring(L, TYPE_NAME);   /* m _type_ */
    89      lua_pushstring(L, "value");     /* m _type_ value */
    90      lua_rawset(L, -3);
    91      return 1;
    92  }
    93  
    94  static int state_var(lua_State *L)
    95  {
    96      const char *var_name;
    97      int t;
    98  
    99      luaL_checktype(L, 1, LUA_TTABLE);           /* T */
   100      lua_pushnil(L);                             /* T nil ; push the first key */
   101      while (lua_next(L, -2) != 0) {              /* T key value */
   102          var_name = luaL_checkstring(L, -2);
   103          t = lua_type(L, -1);
   104  
   105          luaL_checktype(L, -1, LUA_TTABLE);
   106          lua_pushstring(L, "id");                /* T key value id */
   107          lua_pushvalue(L, -3);                   /* T key value id key */
   108          lua_rawset(L, -3);                      /* T key value{id=key} */
   109  
   110          lua_pushstring(L, TYPE_NAME);           /* T key value _type_ */
   111          lua_rawget(L, -2);                      /* T key value "type_name" */
   112          if (lua_isnil(L, -1)) {
   113              lua_pushfstring(L, "bad argument " LUA_QL("%s") ": state.value, state.map or state.array expected, got %s",
   114                              var_name, lua_typename(L, t));
   115              lua_error(L);
   116          }
   117          lua_getglobal(L, "abi");                /* T key value "type_name" m */
   118          lua_getfield(L, -1, "register_var");    /* T key value "type_name" m f */
   119          lua_pushstring(L, var_name);            /* T key value "type_name" m f var_name */
   120          lua_pushvalue(L, -5);                   /* T key value "type_name" m f var_name VT */
   121          lua_call(L, 2, 0);                      /* T key value "type_name" m */
   122          lua_pop(L, 2);                          /* T key value */
   123          lua_setglobal(L, var_name);             /* T key */
   124      }
   125      return 0;
   126  }
   127  
   128  int luac_open_state(lua_State *L)
   129  {
   130      static const luaL_Reg state_lib[] = {
   131          {"map", state_map},
   132          {"array", state_array},
   133          {"value", state_value},
   134          {"var", state_var},
   135          {NULL, NULL}
   136      };
   137  
   138      luaL_register(L, "state", state_lib);
   139  
   140      return 1;
   141  }