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 }