lapi.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. ** $Id: lapi.c,v 1.88 2000/08/28 17:57:04 roberto Exp roberto $
  3. ** Lua API
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <string.h>
  7. #include "lua.h"
  8. #include "lapi.h"
  9. #include "lauxlib.h"
  10. #include "ldo.h"
  11. #include "lfunc.h"
  12. #include "lgc.h"
  13. #include "lmem.h"
  14. #include "lobject.h"
  15. #include "lstate.h"
  16. #include "lstring.h"
  17. #include "ltable.h"
  18. #include "ltm.h"
  19. #include "lvm.h"
  20. const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
  21. "$Authors: " LUA_AUTHORS " $";
  22. #define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
  23. #define api_incr_top(L) (++L->top)
  24. TObject *luaA_index (lua_State *L, int index) {
  25. return Index(L, index);
  26. }
  27. void luaA_pushobject (lua_State *L, const TObject *o) {
  28. *L->top = *o;
  29. incr_top;
  30. }
  31. /*
  32. ** basic stack manipulation
  33. */
  34. int lua_gettop (lua_State *L) {
  35. return (L->top - L->Cbase);
  36. }
  37. void lua_settop (lua_State *L, int index) {
  38. if (index >= 0)
  39. luaD_adjusttop(L, L->Cbase, index);
  40. else
  41. L->top += index; /* index is negative */
  42. }
  43. void lua_pushobject (lua_State *L, int index) {
  44. *L->top = *Index(L, index);
  45. api_incr_top(L);
  46. }
  47. /*
  48. ** access functions (stack -> C)
  49. */
  50. #define btest(L,i,value,default) { \
  51. StkId o; \
  52. if ((i) >= 0) { \
  53. o = L->Cbase+((i)-1); \
  54. if (o >= L->top) return (default); \
  55. } \
  56. else o = L->top+(i); \
  57. return (value); }
  58. #define access(L,i,test,default,value) { \
  59. StkId o; \
  60. if ((i) >= 0) { \
  61. o = L->Cbase+((i)-1); \
  62. if (o >= L->top) return (default); \
  63. } \
  64. else o = L->top+(i); \
  65. return ((test) ? (value) : (default)); }
  66. const char *lua_type (lua_State *L, int index) {
  67. btest(L, index, luaO_typename(o), "NO VALUE");
  68. }
  69. int lua_iscfunction (lua_State *L, int index) {
  70. btest(L, index, (ttype(o) == TAG_CCLOSURE), 0);
  71. }
  72. int lua_isnumber (lua_State *L, int index) {
  73. btest(L, index, (tonumber(Index(L, index)) == 0), 0);
  74. }
  75. int lua_tag (lua_State *L, int index) {
  76. btest(L, index,
  77. ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)),
  78. -1);
  79. }
  80. int lua_equal(lua_State *L, int index1, int index2) {
  81. StkId o1 = Index(L, index1);
  82. StkId o2 = Index(L, index2);
  83. if (o1 >= L->top || o2 >= L->top) return 0; /* index out-of-range */
  84. else return luaO_equalObj(o1, o2);
  85. }
  86. double lua_tonumber (lua_State *L, int index) {
  87. access(L, index, (tonumber(o) == 0), 0.0, nvalue(o));
  88. }
  89. const char *lua_tostring (lua_State *L, int index) {
  90. luaC_checkGC(L); /* `tostring' may create a new string */
  91. access(L, index, (tostring(L, o) == 0), NULL, svalue(o));
  92. }
  93. size_t lua_strlen (lua_State *L, int index) {
  94. access(L, index, (tostring(L, o) == 0), 0, tsvalue(o)->u.s.len);
  95. }
  96. lua_CFunction lua_tocfunction (lua_State *L, int index) {
  97. access(L, index, (ttype(o) == TAG_CCLOSURE), NULL, clvalue(o)->f.c);
  98. }
  99. void *lua_touserdata (lua_State *L, int index) {
  100. access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value);
  101. }
  102. /*
  103. ** push functions (C -> stack)
  104. */
  105. void lua_pushnil (lua_State *L) {
  106. ttype(L->top) = TAG_NIL;
  107. api_incr_top(L);
  108. }
  109. void lua_pushnumber (lua_State *L, double n) {
  110. ttype(L->top) = TAG_NUMBER;
  111. nvalue(L->top) = n;
  112. api_incr_top(L);
  113. }
  114. void lua_pushlstring (lua_State *L, const char *s, size_t len) {
  115. luaC_checkGC(L);
  116. tsvalue(L->top) = luaS_newlstr(L, s, len);
  117. ttype(L->top) = TAG_STRING;
  118. api_incr_top(L);
  119. }
  120. void lua_pushstring (lua_State *L, const char *s) {
  121. if (s == NULL)
  122. lua_pushnil(L);
  123. else
  124. lua_pushlstring(L, s, strlen(s));
  125. }
  126. void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
  127. luaC_checkGC(L);
  128. luaV_Cclosure(L, fn, n);
  129. }
  130. void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */
  131. luaC_checkGC(L);
  132. if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS)
  133. luaL_verror(L, "invalid tag for a userdata (%d)", tag);
  134. tsvalue(L->top) = luaS_createudata(L, u, tag);
  135. ttype(L->top) = TAG_USERDATA;
  136. api_incr_top(L);
  137. }
  138. /*
  139. ** get functions (Lua -> stack)
  140. */
  141. void lua_getglobal (lua_State *L, const char *name) {
  142. luaV_getglobal(L, luaS_new(L, name), L->top++);
  143. }
  144. void lua_gettable (lua_State *L) {
  145. luaV_gettable(L, L->top--);
  146. }
  147. void lua_rawget (lua_State *L) {
  148. if (ttype(L->top - 2) != TAG_TABLE)
  149. lua_error(L, "indexed expression not a table");
  150. *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
  151. L->top--;
  152. }
  153. void lua_getglobals (lua_State *L) {
  154. hvalue(L->top) = L->gt;
  155. ttype(L->top) = TAG_TABLE;
  156. api_incr_top(L);
  157. }
  158. void lua_gettagmethod (lua_State *L, int tag, const char *event) {
  159. *L->top = *luaT_gettagmethod(L, tag, event);
  160. api_incr_top(L);
  161. }
  162. int lua_getref (lua_State *L, int ref) {
  163. if (ref == LUA_REFNIL)
  164. ttype(L->top) = TAG_NIL;
  165. else if (0 <= ref && ref < L->refSize &&
  166. (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
  167. *L->top = L->refArray[ref].o;
  168. else
  169. return 0;
  170. api_incr_top(L);
  171. return 1;
  172. }
  173. void lua_newtable (lua_State *L) {
  174. luaC_checkGC(L);
  175. hvalue(L->top) = luaH_new(L, 0);
  176. ttype(L->top) = TAG_TABLE;
  177. api_incr_top(L);
  178. }
  179. /*
  180. ** set functions (stack -> Lua)
  181. */
  182. void lua_setglobal (lua_State *L, const char *name) {
  183. luaV_setglobal(L, luaS_new(L, name), L->top--);
  184. }
  185. void lua_settable (lua_State *L) {
  186. StkId top = L->top;
  187. luaV_settable(L, top-3, top);
  188. L->top = top-3; /* pop table, index, and value */
  189. }
  190. void lua_rawset (lua_State *L) {
  191. if (ttype(L->top-3) != TAG_TABLE)
  192. lua_error(L, "indexed expression not a table");
  193. *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
  194. L->top -= 3;
  195. }
  196. void lua_setglobals (lua_State *L) {
  197. TObject *newtable = --L->top;
  198. if (ttype(newtable) != TAG_TABLE)
  199. lua_error(L, "Lua API error - invalid value for global table");
  200. L->gt = hvalue(newtable);
  201. }
  202. void lua_settagmethod (lua_State *L, int tag, const char *event) {
  203. TObject *method = L->top - 1;
  204. if (ttype(method) != TAG_NIL &&
  205. ttype(method) != TAG_CCLOSURE &&
  206. ttype(method) != TAG_LCLOSURE)
  207. lua_error(L, "Lua API error - tag method must be a function or nil");
  208. luaT_settagmethod(L, tag, event, method);
  209. }
  210. int lua_ref (lua_State *L, int lock) {
  211. int ref;
  212. if (ttype(L->top-1) == TAG_NIL)
  213. ref = LUA_REFNIL;
  214. else {
  215. if (L->refFree != NONEXT) { /* is there a free place? */
  216. ref = L->refFree;
  217. L->refFree = L->refArray[ref].st;
  218. }
  219. else { /* no more free places */
  220. luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
  221. "reference table overflow", MAX_INT);
  222. ref = L->refSize++;
  223. }
  224. L->refArray[ref].o = *(L->top-1);
  225. L->refArray[ref].st = lock ? LOCK : HOLD;
  226. }
  227. L->top--;
  228. return ref;
  229. }
  230. /*
  231. ** miscelaneous functions
  232. */
  233. void lua_settag (lua_State *L, int tag) {
  234. luaT_realtag(L, tag);
  235. switch (ttype(L->top-1)) {
  236. case TAG_TABLE:
  237. hvalue(L->top-1)->htag = tag;
  238. break;
  239. case TAG_USERDATA:
  240. tsvalue(L->top-1)->u.d.tag = tag;
  241. break;
  242. default:
  243. luaL_verror(L, "cannot change the tag of a %.20s",
  244. luaO_typename(L->top-1));
  245. }
  246. L->top--;
  247. }
  248. void lua_unref (lua_State *L, int ref) {
  249. if (ref >= 0) {
  250. if (ref >= L->refSize || L->refArray[ref].st >= 0)
  251. lua_error(L, "Lua API error - "
  252. "invalid argument for function `lua_unref'");
  253. L->refArray[ref].st = L->refFree;
  254. L->refFree = ref;
  255. }
  256. }
  257. int luaA_next (lua_State *L, const Hash *t, int i) {
  258. int tsize = t->size;
  259. for (; i<tsize; i++) {
  260. Node *n = node(t, i);
  261. if (ttype(val(n)) != TAG_NIL) {
  262. luaA_pushobject(L, key(n));
  263. luaA_pushobject(L, val(n));
  264. return i+1; /* index to be used next time */
  265. }
  266. }
  267. return 0; /* no more elements */
  268. }
  269. int lua_next (lua_State *L, int index, int i) {
  270. const TObject *t = Index(L, index);
  271. if (ttype(t) != TAG_TABLE)
  272. lua_error(L, "Lua API error - object is not a table in `lua_next'");
  273. return luaA_next(L, hvalue(t), i);
  274. }