lbuiltin.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*
  2. ** $Id: lbuiltin.c,v 1.44 1999/01/04 12:55:09 roberto Exp roberto $
  3. ** Built-in functions
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "lapi.h"
  11. #include "lauxlib.h"
  12. #include "lbuiltin.h"
  13. #include "ldo.h"
  14. #include "lfunc.h"
  15. #include "lmem.h"
  16. #include "lobject.h"
  17. #include "lstate.h"
  18. #include "lstring.h"
  19. #include "ltable.h"
  20. #include "ltm.h"
  21. #include "lua.h"
  22. #include "lundump.h"
  23. #include "lvm.h"
  24. /*
  25. ** {======================================================
  26. ** Auxliliar functions
  27. ** =======================================================
  28. */
  29. static void pushtagstring (TaggedString *s) {
  30. TObject o;
  31. o.ttype = LUA_T_STRING;
  32. o.value.ts = s;
  33. luaA_pushobject(&o);
  34. }
  35. static real getsize (Hash *h) {
  36. real max = 0;
  37. int i;
  38. for (i = 0; i<nhash(h); i++) {
  39. Node *n = h->node+i;
  40. if (ttype(ref(n)) == LUA_T_NUMBER &&
  41. ttype(val(n)) != LUA_T_NIL &&
  42. nvalue(ref(n)) > max)
  43. max = nvalue(ref(n));
  44. }
  45. return max;
  46. }
  47. static real getnarg (Hash *a) {
  48. TObject index;
  49. TObject *value;
  50. /* value = table.n */
  51. ttype(&index) = LUA_T_STRING;
  52. tsvalue(&index) = luaS_new("n");
  53. value = luaH_get(a, &index);
  54. return (ttype(value) == LUA_T_NUMBER) ? nvalue(value) : getsize(a);
  55. }
  56. static Hash *gethash (int arg) {
  57. return avalue(luaA_Address(luaL_tablearg(arg)));
  58. }
  59. static void luaB_getn (void) {
  60. lua_pushnumber(getnarg(gethash(1)));
  61. }
  62. /* }====================================================== */
  63. /*
  64. ** {======================================================
  65. ** Functions that use only the official API
  66. ** =======================================================
  67. */
  68. /*
  69. ** If your system does not support "stderr", remove this function and
  70. ** define your own "_ALERT" function. You *must* have an _ALERT function
  71. ** defined for Lua to work properly.
  72. */
  73. static void luaB_alert (void) {
  74. fputs(luaL_check_string(1), stderr);
  75. }
  76. /*
  77. ** Standard implementation of _ERRORMESSAGE.
  78. ** The library "iolib" redefines _ERRORMESSAGE for better error information.
  79. */
  80. static void error_message (void) {
  81. char buff[600];
  82. sprintf(buff, "lua error: %.500s\n", luaL_check_string(1));
  83. lua_pushstring(buff);
  84. lua_call("_ALERT");
  85. }
  86. /*
  87. ** If your system does not support "stdout", just remove this function.
  88. ** If you need, you can define your own "print" function, following this
  89. ** model but changing "fputs" to put the strings at a proper place
  90. ** (a console window or a log file, for instance).
  91. */
  92. #define MAXPRINT 40
  93. static void luaB_print (void) {
  94. lua_Object args[MAXPRINT];
  95. lua_Object obj;
  96. int n = 0;
  97. int i;
  98. while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
  99. luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
  100. args[n++] = obj;
  101. }
  102. for (i=0; i<n; i++) {
  103. lua_pushobject(args[i]);
  104. if (lua_call("tostring"))
  105. lua_error("error in `tostring' called by `print'");
  106. obj = lua_getresult(1);
  107. if (!lua_isstring(obj))
  108. lua_error("`tostring' must return a string to `print'");
  109. if (i>0) fputs("\t", stdout);
  110. fputs(lua_getstring(obj), stdout);
  111. }
  112. fputs("\n", stdout);
  113. }
  114. static void luaB_tonumber (void) {
  115. int base = luaL_opt_int(2, 10);
  116. if (base == 10) { /* standard conversion */
  117. lua_Object o = lua_getparam(1);
  118. if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o));
  119. else lua_pushnil(); /* not a number */
  120. }
  121. else {
  122. char *s = luaL_check_string(1);
  123. long n;
  124. luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
  125. n = strtol(s, &s, base);
  126. while (isspace(*s)) s++; /* skip trailing spaces */
  127. if (*s) lua_pushnil(); /* invalid format: return nil */
  128. else lua_pushnumber(n);
  129. }
  130. }
  131. static void luaB_error (void) {
  132. lua_error(lua_getstring(lua_getparam(1)));
  133. }
  134. static void luaB_setglobal (void) {
  135. char *n = luaL_check_string(1);
  136. lua_Object value = luaL_nonnullarg(2);
  137. lua_pushobject(value);
  138. lua_setglobal(n);
  139. lua_pushobject(value); /* return given value */
  140. }
  141. static void luaB_rawsetglobal (void) {
  142. char *n = luaL_check_string(1);
  143. lua_Object value = luaL_nonnullarg(2);
  144. lua_pushobject(value);
  145. lua_rawsetglobal(n);
  146. lua_pushobject(value); /* return given value */
  147. }
  148. static void luaB_getglobal (void) {
  149. lua_pushobject(lua_getglobal(luaL_check_string(1)));
  150. }
  151. static void luaB_rawgetglobal (void) {
  152. lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
  153. }
  154. static void luaB_luatag (void) {
  155. lua_pushnumber(lua_tag(lua_getparam(1)));
  156. }
  157. static void luaB_settag (void) {
  158. lua_Object o = luaL_tablearg(1);
  159. lua_pushobject(o);
  160. lua_settag(luaL_check_int(2));
  161. lua_pushobject(o); /* returns first argument */
  162. }
  163. static void luaB_newtag (void) {
  164. lua_pushnumber(lua_newtag());
  165. }
  166. static void luaB_copytagmethods (void) {
  167. lua_pushnumber(lua_copytagmethods(luaL_check_int(1),
  168. luaL_check_int(2)));
  169. }
  170. static void luaB_rawgettable (void) {
  171. lua_pushobject(luaL_nonnullarg(1));
  172. lua_pushobject(luaL_nonnullarg(2));
  173. lua_pushobject(lua_rawgettable());
  174. }
  175. static void luaB_rawsettable (void) {
  176. lua_pushobject(luaL_nonnullarg(1));
  177. lua_pushobject(luaL_nonnullarg(2));
  178. lua_pushobject(luaL_nonnullarg(3));
  179. lua_rawsettable();
  180. }
  181. static void luaB_settagmethod (void) {
  182. lua_Object nf = luaL_nonnullarg(3);
  183. lua_pushobject(nf);
  184. lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2)));
  185. }
  186. static void luaB_gettagmethod (void) {
  187. lua_pushobject(lua_gettagmethod(luaL_check_int(1), luaL_check_string(2)));
  188. }
  189. static void luaB_seterrormethod (void) {
  190. lua_Object nf = luaL_functionarg(1);
  191. lua_pushobject(nf);
  192. lua_pushobject(lua_seterrormethod());
  193. }
  194. static void luaB_collectgarbage (void) {
  195. lua_pushnumber(lua_collectgarbage(luaL_opt_int(1, 0)));
  196. }
  197. /* }====================================================== */
  198. /*
  199. ** {======================================================
  200. ** Functions that could use only the official API but
  201. ** do not, for efficiency.
  202. ** =======================================================
  203. */
  204. static void luaB_dostring (void) {
  205. long l;
  206. char *s = luaL_check_lstr(1, &l);
  207. if (*s == ID_CHUNK)
  208. lua_error("`dostring' cannot run pre-compiled code");
  209. if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0)
  210. if (luaA_passresults() == 0)
  211. lua_pushuserdata(NULL); /* at least one result to signal no errors */
  212. }
  213. static void luaB_dofile (void) {
  214. char *fname = luaL_opt_string(1, NULL);
  215. if (lua_dofile(fname) == 0)
  216. if (luaA_passresults() == 0)
  217. lua_pushuserdata(NULL); /* at least one result to signal no errors */
  218. }
  219. static void luaB_call (void) {
  220. lua_Object f = luaL_nonnullarg(1);
  221. Hash *arg = gethash(2);
  222. char *options = luaL_opt_string(3, "");
  223. lua_Object err = lua_getparam(4);
  224. int narg = (int)getnarg(arg);
  225. int i, status;
  226. if (err != LUA_NOOBJECT) { /* set new error method */
  227. lua_pushobject(err);
  228. err = lua_seterrormethod();
  229. }
  230. /* push arg[1...n] */
  231. luaD_checkstack(narg);
  232. for (i=0; i<narg; i++)
  233. *(L->stack.top++) = *luaH_getint(arg, i+1);
  234. status = lua_callfunction(f);
  235. if (err != LUA_NOOBJECT) { /* restore old error method */
  236. lua_pushobject(err);
  237. lua_seterrormethod();
  238. }
  239. if (status != 0) { /* error in call? */
  240. if (strchr(options, 'x')) {
  241. lua_pushnil();
  242. return; /* return nil to signal the error */
  243. }
  244. else
  245. lua_error(NULL);
  246. }
  247. else { /* no errors */
  248. if (strchr(options, 'p'))
  249. luaA_packresults();
  250. else
  251. luaA_passresults();
  252. }
  253. }
  254. /* }====================================================== */
  255. /*
  256. ** {======================================================
  257. ** "Extra" functions
  258. ** These functions can be written in Lua, so you can
  259. ** delete them if you need a tiny Lua implementation.
  260. ** If you delete them, remove their entries in array
  261. ** "builtin_funcs".
  262. ** =======================================================
  263. */
  264. static void luaB_assert (void) {
  265. lua_Object p = lua_getparam(1);
  266. if (p == LUA_NOOBJECT || lua_isnil(p))
  267. luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
  268. }
  269. static void luaB_foreachi (void) {
  270. Hash *t = gethash(1);
  271. TObject f = *luaA_Address(luaL_functionarg(2));
  272. int i;
  273. int n = (int)getnarg(t);
  274. luaD_checkstack(3); /* for f, ref, and val */
  275. for (i=1; i<=n; i++) {
  276. *(L->stack.top++) = f;
  277. ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i;
  278. *(L->stack.top++) = *luaH_getint(t, i);
  279. luaD_calln(2, 1);
  280. if (ttype(L->stack.top-1) != LUA_T_NIL)
  281. return;
  282. L->stack.top--;
  283. }
  284. }
  285. static void luaB_foreach (void) {
  286. Hash *a = gethash(1);
  287. TObject f = *luaA_Address(luaL_functionarg(2));
  288. int i;
  289. luaD_checkstack(3); /* for f, ref, and val */
  290. for (i=0; i<a->nhash; i++) {
  291. Node *nd = &(a->node[i]);
  292. if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) {
  293. *(L->stack.top++) = f;
  294. *(L->stack.top++) = *ref(nd);
  295. *(L->stack.top++) = *val(nd);
  296. luaD_calln(2, 1);
  297. if (ttype(L->stack.top-1) != LUA_T_NIL)
  298. return;
  299. L->stack.top--;
  300. }
  301. }
  302. }
  303. static void luaB_foreachvar (void) {
  304. TObject f = *luaA_Address(luaL_functionarg(1));
  305. GCnode *g;
  306. StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */
  307. luaD_checkstack(4); /* for var name, f, s, and globalvar */
  308. ttype(L->stack.stack+name) = LUA_T_NIL;
  309. L->stack.top++; /* top == base */
  310. for (g = L->rootglobal.next; g; g = g->next) {
  311. TaggedString *s = (TaggedString *)g;
  312. if (s->u.s.globalval.ttype != LUA_T_NIL) {
  313. ttype(L->stack.stack+name) = LUA_T_STRING;
  314. tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
  315. *(L->stack.top++) = f;
  316. pushtagstring(s);
  317. *(L->stack.top++) = s->u.s.globalval;
  318. luaD_calln(2, 1);
  319. if (ttype(L->stack.top-1) != LUA_T_NIL)
  320. return;
  321. L->stack.top--;
  322. }
  323. }
  324. }
  325. static void luaB_tinsert (void) {
  326. Hash *a = gethash(1);
  327. lua_Object v = lua_getparam(3);
  328. int n = (int)getnarg(a);
  329. int pos;
  330. if (v != LUA_NOOBJECT)
  331. pos = luaL_check_int(2);
  332. else { /* called with only 2 arguments */
  333. v = luaL_nonnullarg(2);
  334. pos = n+1;
  335. }
  336. luaV_setn(a, n+1); /* increment field "n" */
  337. for ( ;n>=pos; n--)
  338. luaH_move(a, n, n+1);
  339. luaH_setint(a, pos, luaA_Address(v));
  340. }
  341. static void luaB_tremove (void) {
  342. Hash *a = gethash(1);
  343. int n = (int)getnarg(a);
  344. int pos = luaL_opt_int(2, n);
  345. TObject v = *luaH_getint(a, pos);
  346. if (n <= 0) return; /* table is "empty" */
  347. luaV_setn(a, n-1); /* decrement field "n" */
  348. for ( ;pos<n; pos++)
  349. luaH_move(a, pos+1, pos);
  350. luaA_pushobject(&v);
  351. }
  352. /* {
  353. ** Quicksort
  354. */
  355. static void swap (Hash *a, int i, int j) {
  356. TObject temp = *luaH_getint(a, i);
  357. luaH_move(a, j, i);
  358. luaH_setint(a, j, &temp);
  359. }
  360. static int sort_comp (TObject *f, TObject *a, TObject *b) {
  361. /* notice: the caller (auxsort) must check stack space */
  362. if (f) {
  363. *(L->stack.top) = *f;
  364. *(L->stack.top+1) = *a;
  365. *(L->stack.top+2) = *b;
  366. L->stack.top += 3;
  367. luaD_calln(2, 1);
  368. }
  369. else { /* a < b? */
  370. *(L->stack.top) = *a;
  371. *(L->stack.top+1) = *b;
  372. L->stack.top += 2;
  373. luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
  374. }
  375. return ttype(--(L->stack.top)) != LUA_T_NIL;
  376. }
  377. static void auxsort (Hash *a, int l, int u, TObject *f) {
  378. while (l < u) { /* for tail recursion */
  379. TObject *P;
  380. int i, j;
  381. /* sort elements a[l], a[(l+u)/2] and a[u] */
  382. if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */
  383. swap(a, l, u);
  384. if (u-l == 1) break; /* only 2 elements */
  385. i = (l+u)/2;
  386. P = luaH_getint(a, i);
  387. if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */
  388. swap(a, l, i);
  389. else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */
  390. swap(a, i, u);
  391. if (u-l == 2) break; /* only 3 elements */
  392. P = L->stack.top++;
  393. *P = *luaH_getint(a, i); /* save pivot on stack (for GC) */
  394. swap(a, i, u-1); /* put median element as pivot (a[u-1]) */
  395. /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
  396. i = l; j = u-1;
  397. for (;;) {
  398. /* invariant: a[l..i] <= P <= a[j..u] */
  399. while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */
  400. if (i>u) lua_error("invalid order function for sorting");
  401. while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */
  402. if (j<l) lua_error("invalid order function for sorting");
  403. if (j<i) break;
  404. swap(a, i, j);
  405. }
  406. swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */
  407. L->stack.top--; /* remove pivot from stack */
  408. /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
  409. /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
  410. if (i-l < u-i) {
  411. j=l; i=i-1; l=i+2;
  412. }
  413. else {
  414. j=i+1; i=u; u=j-2;
  415. }
  416. auxsort(a, j, i, f); /* call recursively the smaller one */
  417. } /* repeat the routine for the larger one */
  418. }
  419. static void luaB_sort (void) {
  420. lua_Object t = lua_getparam(1);
  421. Hash *a = gethash(1);
  422. int n = (int)getnarg(a);
  423. lua_Object func = lua_getparam(2);
  424. TObject *f = luaA_Address(func);
  425. luaL_arg_check(!f || lua_isfunction(func), 2, "function expected");
  426. luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */
  427. auxsort(a, 1, n, f);
  428. lua_pushobject(t);
  429. }
  430. /* }}===================================================== */
  431. /*
  432. ** {======================================================
  433. ** Internal Functions.
  434. ** These functions need access to internal structures
  435. ** to be implemented.
  436. ** =======================================================
  437. */
  438. static void luaB_nextvar (void) {
  439. TObject *o = luaA_Address(luaL_nonnullarg(1));
  440. TaggedString *g;
  441. if (ttype(o) == LUA_T_NIL)
  442. g = (TaggedString *)L->rootglobal.next; /* first variable */
  443. else {
  444. luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
  445. g = tsvalue(o); /* find given variable name */
  446. /* check whether name is in global var list */
  447. luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
  448. g = (TaggedString *)g->head.next; /* get next */
  449. }
  450. while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
  451. g = (TaggedString *)g->head.next;
  452. if (g) {
  453. pushtagstring(g);
  454. luaA_pushobject(&g->u.s.globalval);
  455. }
  456. else lua_pushnil(); /* no more globals */
  457. }
  458. static void luaB_next (void) {
  459. Node *n = luaH_next(gethash(1), luaA_Address(luaL_nonnullarg(2)));
  460. if (n) {
  461. luaA_pushobject(&n->ref);
  462. luaA_pushobject(&n->val);
  463. }
  464. else lua_pushnil();
  465. }
  466. static void luaB_tostring (void) {
  467. lua_Object obj = lua_getparam(1);
  468. TObject *o = luaA_Address(obj);
  469. char buff[64];
  470. switch (ttype(o)) {
  471. case LUA_T_NUMBER:
  472. lua_pushstring(lua_getstring(obj));
  473. return;
  474. case LUA_T_STRING:
  475. lua_pushobject(obj);
  476. return;
  477. case LUA_T_ARRAY:
  478. sprintf(buff, "table: %p", (void *)o->value.a);
  479. break;
  480. case LUA_T_CLOSURE:
  481. sprintf(buff, "function: %p", (void *)o->value.cl);
  482. break;
  483. case LUA_T_PROTO:
  484. sprintf(buff, "function: %p", (void *)o->value.tf);
  485. break;
  486. case LUA_T_CPROTO:
  487. sprintf(buff, "function: %p", (void *)o->value.f);
  488. break;
  489. case LUA_T_USERDATA:
  490. sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
  491. break;
  492. case LUA_T_NIL:
  493. lua_pushstring("nil");
  494. return;
  495. default:
  496. LUA_INTERNALERROR("invalid type");
  497. }
  498. lua_pushstring(buff);
  499. }
  500. static void luaB_type (void) {
  501. lua_Object o = luaL_nonnullarg(1);
  502. lua_pushstring(luaO_typename(luaA_Address(o)));
  503. lua_pushnumber(lua_tag(o));
  504. }
  505. /* }====================================================== */
  506. #ifdef DEBUG
  507. /*
  508. ** {======================================================
  509. ** some DEBUG functions
  510. ** =======================================================
  511. */
  512. static void mem_query (void) {
  513. lua_pushnumber(totalmem);
  514. lua_pushnumber(numblocks);
  515. }
  516. static void countlist (void) {
  517. char *s = luaL_check_string(1);
  518. GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
  519. (s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
  520. int i=0;
  521. while (l) {
  522. i++;
  523. l = l->next;
  524. }
  525. lua_pushnumber(i);
  526. }
  527. static void testC (void) {
  528. #define getnum(s) ((*s++) - '0')
  529. #define getname(s) (nome[0] = *s++, nome)
  530. static int locks[10];
  531. lua_Object reg[10];
  532. char nome[2];
  533. char *s = luaL_check_string(1);
  534. nome[1] = 0;
  535. for (;;) {
  536. switch (*s++) {
  537. case '0': case '1': case '2': case '3': case '4':
  538. case '5': case '6': case '7': case '8': case '9':
  539. lua_pushnumber(*(s-1) - '0');
  540. break;
  541. case 'c': reg[getnum(s)] = lua_createtable(); break;
  542. case 'C': { lua_CFunction f = lua_getcfunction(lua_getglobal(getname(s)));
  543. lua_pushcclosure(f, getnum(s));
  544. break;
  545. }
  546. case 'P': reg[getnum(s)] = lua_pop(); break;
  547. case 'g': { int n=getnum(s); reg[n]=lua_getglobal(getname(s)); break; }
  548. case 'G': { int n = getnum(s);
  549. reg[n] = lua_rawgetglobal(getname(s));
  550. break;
  551. }
  552. case 'l': locks[getnum(s)] = lua_ref(1); break;
  553. case 'L': locks[getnum(s)] = lua_ref(0); break;
  554. case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; }
  555. case 'u': lua_unref(locks[getnum(s)]); break;
  556. case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; }
  557. case '=': lua_setglobal(getname(s)); break;
  558. case 's': lua_pushstring(getname(s)); break;
  559. case 'o': lua_pushobject(reg[getnum(s)]); break;
  560. case 'f': (lua_call)(getname(s)); break;
  561. case 'i': reg[getnum(s)] = lua_gettable(); break;
  562. case 'I': reg[getnum(s)] = lua_rawgettable(); break;
  563. case 't': lua_settable(); break;
  564. case 'T': lua_rawsettable(); break;
  565. default: luaL_verror("unknown command in `testC': %c", *(s-1));
  566. }
  567. if (*s == 0) return;
  568. if (*s++ != ' ') lua_error("missing ` ' between commands in `testC'");
  569. }
  570. }
  571. /* }====================================================== */
  572. #endif
  573. static struct luaL_reg builtin_funcs[] = {
  574. #ifdef LUA_COMPAT2_5
  575. {"setfallback", luaT_setfallback},
  576. #endif
  577. #ifdef DEBUG
  578. {"testC", testC},
  579. {"totalmem", mem_query},
  580. {"count", countlist},
  581. #endif
  582. {"_ALERT", luaB_alert},
  583. {"_ERRORMESSAGE", error_message},
  584. {"call", luaB_call},
  585. {"collectgarbage", luaB_collectgarbage},
  586. {"copytagmethods", luaB_copytagmethods},
  587. {"dofile", luaB_dofile},
  588. {"dostring", luaB_dostring},
  589. {"error", luaB_error},
  590. {"getglobal", luaB_getglobal},
  591. {"getn", luaB_getn},
  592. {"gettagmethod", luaB_gettagmethod},
  593. {"newtag", luaB_newtag},
  594. {"next", luaB_next},
  595. {"nextvar", luaB_nextvar},
  596. {"print", luaB_print},
  597. {"rawgetglobal", luaB_rawgetglobal},
  598. {"rawgettable", luaB_rawgettable},
  599. {"rawsetglobal", luaB_rawsetglobal},
  600. {"rawsettable", luaB_rawsettable},
  601. {"seterrormethod", luaB_seterrormethod},
  602. {"setglobal", luaB_setglobal},
  603. {"settag", luaB_settag},
  604. {"settagmethod", luaB_settagmethod},
  605. {"tag", luaB_luatag},
  606. {"tonumber", luaB_tonumber},
  607. {"tostring", luaB_tostring},
  608. {"type", luaB_type},
  609. /* "Extra" functions */
  610. {"assert", luaB_assert},
  611. {"foreach", luaB_foreach},
  612. {"foreachi", luaB_foreachi},
  613. {"foreachvar", luaB_foreachvar},
  614. {"sort", luaB_sort},
  615. {"tinsert", luaB_tinsert},
  616. {"tremove", luaB_tremove}
  617. };
  618. #define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))
  619. void luaB_predefine (void) {
  620. /* pre-register mem error messages, to avoid loop when error arises */
  621. luaS_newfixedstring(tableEM);
  622. luaS_newfixedstring(memEM);
  623. luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])));
  624. lua_pushstring(LUA_VERSION);
  625. lua_setglobal("_VERSION");
  626. }