Преглед изворни кода

more builtin functions using official API

Roberto Ierusalimschy пре 25 година
родитељ
комит
9a21e81907
3 измењених фајлова са 115 додато и 96 уклоњено
  1. 43 5
      lapi.c
  2. 69 90
      lbuiltin.c
  3. 3 1
      lua.h

+ 43 - 5
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.91 2000/08/31 14:08:27 roberto Exp roberto $
+** $Id: lapi.c,v 1.92 2000/08/31 20:23:40 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -167,6 +167,23 @@ void *lua_touserdata (lua_State *L, int index) {
   access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value);
 }
 
+const void *lua_topointer (lua_State *L, int index) {
+  const TObject *o = Index(L, index);
+  switch (ttype(o)) {
+    case TAG_NUMBER:  case TAG_NIL:
+      return NULL;
+    case TAG_STRING:
+      return tsvalue(o)->str;
+    case TAG_USERDATA:
+      return tsvalue(o)->u.d.value;
+    case TAG_TABLE: 
+      return hvalue(o);
+    case TAG_CCLOSURE: case TAG_LCLOSURE:
+      return clvalue(o);
+    default: return NULL;
+  }
+}
+
 
 
 /*
@@ -236,7 +253,7 @@ void lua_gettable (lua_State *L) {
 
 
 void lua_rawget (lua_State *L) {
-  LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "not a table");
+  LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "table expected");
   *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
   L->top--;
 }
@@ -295,7 +312,7 @@ void lua_settable (lua_State *L) {
 
 
 void lua_rawset (lua_State *L) {
-  LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "not a table");
+  LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "table expected");
   *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
   L->top -= 3;
 }
@@ -303,7 +320,7 @@ void lua_rawset (lua_State *L) {
 
 void lua_setglobals (lua_State *L) {
   TObject *newtable = --L->top;
-  LUA_ASSERT(ttype(newtable) == TAG_TABLE, "not a table");
+  LUA_ASSERT(ttype(newtable) == TAG_TABLE, "table expected");
   L->gt = hvalue(newtable);
 }
 
@@ -375,7 +392,7 @@ void lua_unref (lua_State *L, int ref) {
 int lua_next (lua_State *L) {
   const TObject *t = Index(L, -2);
   Node *n;
-  LUA_ASSERT(ttype(t) == TAG_TABLE, "object is not a table in `lua_next'");
+  LUA_ASSERT(ttype(t) == TAG_TABLE, "table expected");
   n = luaH_next(L, hvalue(t), Index(L, -1));
   if (n) {
     *(L->top-1) = *key(n);
@@ -389,3 +406,24 @@ int lua_next (lua_State *L) {
   }
 }
 
+
+int lua_getn (lua_State *L, int index) {
+  Hash *h = hvalue(Index(L, index));
+  const TObject *value = luaH_getstr(h, luaS_new(L, "n"));  /* value = h.n */
+  if (ttype(value) == TAG_NUMBER)
+    return (int)nvalue(value);
+  else {
+    Number max = 0;
+    int i = h->size;
+    Node *n = h->node;
+    while (i--) {
+      if (ttype(key(n)) == TAG_NUMBER &&
+          ttype(val(n)) != TAG_NIL &&
+          nvalue(key(n)) > max)
+        max = nvalue(key(n));
+      n++;
+    }
+    return (int)max;
+  }
+}
+

+ 69 - 90
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.126 2000/08/31 16:52:06 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.127 2000/08/31 20:23:40 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -270,71 +270,15 @@ int luaB_dofile (lua_State *L) {
   return passresults(L, lua_dofile(L, fname), oldtop);
 }
 
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Functions that could use only the official API but
-** do not, for efficiency.
-** =======================================================
-*/
-
-#include "lapi.h"
-#include "ldo.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lvm.h"
-
-
-/*
-** {======================================================
-** Auxiliary functions
-** =======================================================
-*/
-
-static Number getsize (const Hash *h) {
-  Number max = 0;
-  int i = h->size;
-  Node *n = h->node;
-  while (i--) {
-    if (ttype(key(n)) == TAG_NUMBER && 
-        ttype(val(n)) != TAG_NIL &&
-        nvalue(key(n)) > max)
-      max = nvalue(key(n));
-    n++;
-  }
-  return max;
-}
-
-
-static Number getnarg (lua_State *L, const Hash *a) {
-  const TObject *value = luaH_getstr(a, luaS_new(L, "n"));  /* value = a.n */
-  return (ttype(value) == TAG_NUMBER) ? nvalue(value) : getsize(a);
-}
-
-
-static Hash *gettable (lua_State *L, int arg) {
-  luaL_checktype(L, arg, "table");
-  return hvalue(luaA_index(L, arg));
-}
-
-/* }====================================================== */
-
-
-
 
 int luaB_call (lua_State *L) {
   int oldtop;
-  const Hash *arg = gettable(L, 2);
   const char *options = luaL_opt_string(L, 3, "");
   int err = 0;  /* index of old error method */
-  int n = (int)getnarg(L, arg);
   int i, status;
+  int n;
+  luaL_checktype(L, 2, "table");
+  n = lua_getn(L, 2);
   if (!lua_isnull(L, 4)) {  /* set new error method */
     lua_getglobal(L, LUA_ERRORMESSAGE);
     err = lua_gettop(L);  /* get index */
@@ -345,9 +289,12 @@ int luaB_call (lua_State *L) {
   /* push function */
   lua_pushobject(L, 1);
   /* push arg[1...n] */
-  luaD_checkstack(L, n);
-  for (i=0; i<n; i++)
-    *(L->top++) = *luaH_getnum(arg, i+1);
+  luaL_checkstack(L, n, "too many arguments");
+  for (i=0; i<n; i++) {
+    lua_pushobject(L, 2);
+    lua_pushnumber(L, i+1);
+    lua_rawget(L);
+  }
   status = lua_call(L, n, LUA_MULTRET);
   if (err != 0) {  /* restore old error method */
     lua_pushobject(L, err);
@@ -360,49 +307,80 @@ int luaB_call (lua_State *L) {
       lua_error(L, NULL);  /* propagate error without additional messages */
     return 1;
   }
-  else {  /* no errors */
-    if (strchr(options, 'p')) {  /* pack results? */
-      luaV_pack(L, luaA_index(L, oldtop+1));
-      return 1;  /* only table is returned */
-    }
-    else
-      return lua_gettop(L) - oldtop;  /* results are already on the stack */
-  }
+  if (strchr(options, 'p'))  /* pack results? */
+    lua_error(L, "deprecated option `p' in `call'");
+  return lua_gettop(L) - oldtop;  /* results are already on the stack */
 }
 
 
-
 int luaB_tostring (lua_State *L) {
   char buff[64];
-  const TObject *o;
-  luaL_checktype(L, 1, "any");
-  o = luaA_index(L, 1);
-  switch (ttype(o)) {
-    case TAG_NUMBER:
+  switch (lua_type(L, 1)[2]) {
+    case 'm':  /* nuMber */
       lua_pushstring(L, lua_tostring(L, 1));
       return 1;
-    case TAG_STRING:
+    case 'r':  /* stRing */
       lua_pushobject(L, 1);
       return 1;
-    case TAG_TABLE:
-      sprintf(buff, "table: %p", hvalue(o));
+    case 'b':  /* taBle */
+      sprintf(buff, "table: %p", lua_topointer(L, 1));
       break;
-    case TAG_LCLOSURE:  case TAG_CCLOSURE:
-      sprintf(buff, "function: %p", clvalue(o));
+    case 'n':  /* fuNction */
+      sprintf(buff, "function: %p", lua_topointer(L, 1));
       break;
-    case TAG_USERDATA:
+    case 'e':  /* usErdata */
       sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1));
       break;
-    case TAG_NIL:
+    case 'l':  /* niL */
       lua_pushstring(L, "nil");
       return 1;
     default:
-      LUA_INTERNALERROR("invalid type");
+      luaL_argerror(L, 1, "value expected");
   }
   lua_pushstring(L, buff);
   return 1;
 }
 
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Functions that could use only the official API but
+** do not, for efficiency.
+** =======================================================
+*/
+
+#include "lapi.h"
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+/*
+** {======================================================
+** Auxiliary functions
+** =======================================================
+*/
+
+
+static Hash *gettable (lua_State *L, int arg) {
+  luaL_checktype(L, arg, "table");
+  return hvalue(luaA_index(L, arg));
+}
+
+/* }====================================================== */
+
+
+
+
+
+
 /* }====================================================== */
 
 
@@ -426,7 +404,8 @@ int luaB_assert (lua_State *L) {
 
 
 int luaB_getn (lua_State *L) {
-  lua_pushnumber(L, getnarg(L, gettable(L, 1)));
+  luaL_checktype(L, 1, "table");
+  lua_pushnumber(L, lua_getn(L, 1));
   return 1;
 }
 
@@ -440,7 +419,7 @@ static void t_move (lua_State *L, Hash *t, int from, int to) {
 
 int luaB_tinsert (lua_State *L) {
   Hash *a = gettable(L, 1);
-  int n = (int)getnarg(L, a);
+  int n = lua_getn(L, 1);
   int v = lua_gettop(L);  /* last argument: to be inserted */
   int pos;
   if (v == 2)  /* called with only 2 arguments */
@@ -457,7 +436,7 @@ int luaB_tinsert (lua_State *L) {
 
 int luaB_tremove (lua_State *L) {
   Hash *a = gettable(L, 1);
-  int n = (int)getnarg(L, a);
+  int n = lua_getn(L, 1);
   int pos = luaL_opt_int(L, 2, n);
   if (n <= 0) return 0;  /* table is "empty" */
   luaA_pushobject(L, luaH_getnum(a, pos));  /* result = a[pos] */
@@ -471,7 +450,7 @@ int luaB_tremove (lua_State *L) {
 
 static int luaB_foreachi (lua_State *L) {
   const Hash *t = gettable(L, 1);
-  int n = (int)getnarg(L, t);
+  int n = lua_getn(L, 1);
   int i;
   luaL_checktype(L, 2, "function");
   for (i=1; i<=n; i++) {
@@ -584,7 +563,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) {
 
 int luaB_sort (lua_State *L) {
   Hash *a = gettable(L, 1);
-  int n = (int)getnarg(L, a);
+  int n = lua_getn(L, 1);
   const TObject *func = NULL;
   if (!lua_isnull(L, 2)) {  /* is there a 2nd argument? */
     luaL_checktype(L, 2, "function");

+ 3 - 1
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.63 2000/08/31 14:08:27 roberto Exp roberto $
+** $Id: lua.h,v 1.64 2000/08/31 20:23:40 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** e-mail: [email protected]
@@ -83,6 +83,7 @@ const char    *lua_tostring (lua_State *L, int index);
 size_t         lua_strlen (lua_State *L, int index);
 lua_CFunction  lua_tocfunction (lua_State *L, int index);
 void	      *lua_touserdata (lua_State *L, int index);
+const void    *lua_topointer (lua_State *L, int index);
 
 
 /*
@@ -145,6 +146,7 @@ void	       lua_unref (lua_State *L, int ref);
 long	       lua_collectgarbage (lua_State *L, long limit);
 
 int            lua_next (lua_State *L);
+int            lua_getn (lua_State *L, int index);