aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-08-28 14:57:04 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-08-28 14:57:04 -0300
commit9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761 (patch)
treeda8d97d954e5ffabf9ff275df725f1e0a3a5b3e6 /lapi.c
parentf1fd9b5c2c21f24d25d7813f431a3495702ebea6 (diff)
downloadlua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.tar.gz
lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.tar.bz2
lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.zip
first version for new API
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c432
1 files changed, 211 insertions, 221 deletions
diff --git a/lapi.c b/lapi.c
index 9d7a07ce..86e20807 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.86 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: lapi.c,v 1.87 2000/08/14 19:10:14 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,7 +16,6 @@
16#include "lgc.h" 16#include "lgc.h"
17#include "lmem.h" 17#include "lmem.h"
18#include "lobject.h" 18#include "lobject.h"
19#include "lref.h"
20#include "lstate.h" 19#include "lstate.h"
21#include "lstring.h" 20#include "lstring.h"
22#include "ltable.h" 21#include "ltable.h"
@@ -29,246 +28,148 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
29 28
30 29
31 30
32void luaA_checkCargs (lua_State *L, int nargs) { 31#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
33 if (nargs > L->top-L->Cstack.base)
34 luaL_verror(L, "Lua API error - "
35 "expected at least %d arguments in C2lua stack", nargs);
36}
37
38 32
39lua_Object luaA_putluaObject (lua_State *L, const TObject *o) { 33#define api_incr_top(L) (++L->top)
40 luaD_openstack(L, L->Cstack.base);
41 *L->Cstack.base++ = *o;
42 return L->Cstack.base-1;
43}
44 34
45 35
46static void top2LC (lua_State *L, int n) {
47 /* Put the `n' elements on the top as the Lua2C contents */
48 L->Cstack.base = L->top; /* new base */
49 L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
50 L->Cstack.num = n; /* number of results */
51}
52 36
53 37
54lua_Object lua_pop (lua_State *L) { 38TObject *luaA_index (lua_State *L, int index) {
55 luaA_checkCargs(L, 1); 39 return Index(L, index);
56 if (L->Cstack.base != L->top-1) {
57 luaD_openstack(L, L->Cstack.base);
58 *L->Cstack.base = *(--L->top);
59 }
60 return L->Cstack.base++;
61} 40}
62 41
63 42
64void lua_pushglobals (lua_State *L) { 43void luaA_pushobject (lua_State *L, const TObject *o) {
65 hvalue(L->top) = L->gt; 44 *L->top = *o;
66 ttype(L->top) = TAG_TABLE;
67 incr_top; 45 incr_top;
68} 46}
69 47
70 48
71void lua_setglobals (lua_State *L, lua_Object newtable) {
72 if (lua_type(L, newtable)[0] != 't') /* type == "table"? */
73 lua_error(L, "Lua API error - invalid value for global table");
74 L->gt = hvalue(newtable);
75}
76
77 49
78/* 50/*
79** Get a parameter, returning the object handle or LUA_NOOBJECT on error. 51** basic stack manipulation
80** `number' must be 1 to get the first parameter.
81*/ 52*/
82lua_Object lua_lua2C (lua_State *L, int number) {
83 if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
84 return L->Cstack.lua2C+number-1;
85}
86 53
87 54
88int lua_callfunction (lua_State *L, lua_Object function) { 55int lua_gettop (lua_State *L) {
89 if (function == LUA_NOOBJECT) 56 return (L->top - L->Cbase);
90 return 1;
91 else {
92 luaD_openstack(L, L->Cstack.base);
93 *L->Cstack.base = *function;
94 return luaD_protectedrun(L);
95 }
96} 57}
97 58
98 59
99lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) { 60void lua_settop (lua_State *L, int index) {
100 return luaA_putluaObject(L, luaT_gettagmethod(L, tag, event)); 61 if (index >= 0)
62 luaD_adjusttop(L, L->Cbase, index);
63 else
64 L->top += index; /* index is negative */
101} 65}
102 66
103 67
104lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) { 68void lua_pushobject (lua_State *L, int index) {
105 TObject *method; 69 *L->top = *Index(L, index);
106 luaA_checkCargs(L, 1); 70 api_incr_top(L);
107 method = L->top-1;
108 if ((ttype(method) != TAG_NIL) && (*lua_type(L, method) != 'f'))
109 lua_error(L, "Lua API error - tag method must be a function or nil");
110 luaT_settagmethod(L, tag, event, method);
111 return lua_pop(L);
112} 71}
113 72
114 73
115lua_Object lua_gettable (lua_State *L) {
116 luaA_checkCargs(L, 2);
117 luaV_gettable(L, L->top--);
118 return lua_pop(L);
119}
120
121 74
122lua_Object lua_rawget (lua_State *L) { 75/*
123 lua_Object res; 76** access functions (stack -> C)
124 luaA_checkCargs(L, 2); 77*/
125 if (ttype(L->top-2) != TAG_TABLE)
126 lua_error(L, "indexed expression not a table");
127 res = luaA_putluaObject(L, luaH_get(L, hvalue(L->top-2), L->top-1));
128 L->top -= 2;
129 return res;
130}
131 78
132 79
133void lua_settable (lua_State *L) { 80#define btest(L,i,value,default) { \
134 StkId top; 81 StkId o; \
135 luaA_checkCargs(L, 3); 82 if ((i) >= 0) { \
136 top = L->top; 83 o = L->Cbase+((i)-1); \
137 luaV_settable(L, top-3, top); 84 if (o >= L->top) return (default); \
138 L->top = top-3; /* pop table, index, and value */ 85 } \
139} 86 else o = L->top+(i); \
87 return (value); }
140 88
141 89
142void lua_rawset (lua_State *L) { 90#define access(L,i,test,default,value) { \
143 luaA_checkCargs(L, 3); 91 StkId o; \
144 if (ttype(L->top-3) != TAG_TABLE) 92 if ((i) >= 0) { \
145 lua_error(L, "indexed expression not a table"); 93 o = L->Cbase+((i)-1); \
146 *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); 94 if (o >= L->top) return (default); \
147 L->top -= 3; 95 } \
148} 96 else o = L->top+(i); \
97 return ((test) ? (value) : (default)); }
149 98
150 99
151lua_Object lua_createtable (lua_State *L) { 100const char *lua_type (lua_State *L, int index) {
152 TObject o; 101 btest(L, index, luaO_typename(o), "NO VALUE");
153 luaC_checkGC(L);
154 hvalue(&o) = luaH_new(L, 0);
155 ttype(&o) = TAG_TABLE;
156 return luaA_putluaObject(L, &o);
157} 102}
158 103
159 104int lua_iscfunction (lua_State *L, int index) {
160lua_Object lua_getglobal (lua_State *L, const char *name) { 105 btest(L, index, (ttype(o) == TAG_CCLOSURE), 0);
161 luaV_getglobal(L, luaS_new(L, name), L->top++);
162 return lua_pop(L);
163} 106}
164 107
165 108int lua_isnumber (lua_State *L, int index) {
166void lua_setglobal (lua_State *L, const char *name) { 109 btest(L, index, (tonumber(Index(L, index)) == 0), 0);
167 luaA_checkCargs(L, 1);
168 luaV_setglobal(L, luaS_new(L, name), L->top--);
169} 110}
170 111
171 112int lua_tag (lua_State *L, int index) {
172const char *lua_type (lua_State *L, lua_Object o) { 113 btest(L, index,
173 UNUSED(L); 114 ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)),
174 return (o == LUA_NOOBJECT) ? "NOOBJECT" : luaO_typename(o); 115 -1);
175} 116}
176 117
177int lua_isnil (lua_State *L, lua_Object o) { 118int lua_equal(lua_State *L, int index1, int index2) {
178 UNUSED(L); 119 return luaO_equalObj(Index(L, index1), Index(L, index2));
179 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_NIL);
180} 120}
181 121
182int lua_istable (lua_State *L, lua_Object o) {
183 UNUSED(L);
184 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_TABLE);
185}
186 122
187int lua_isuserdata (lua_State *L, lua_Object o) {
188 UNUSED(L);
189 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_USERDATA);
190}
191 123
192int lua_iscfunction (lua_State *L, lua_Object o) { 124double lua_tonumber (lua_State *L, int index) {
193 UNUSED(L); 125 access(L, index, (tonumber(o) == 0), 0.0, nvalue(o));
194 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_CCLOSURE);
195} 126}
196 127
197int lua_isnumber (lua_State *L, lua_Object o) { 128const char *lua_tostring (lua_State *L, int index) {
198 UNUSED(L); 129 luaC_checkGC(L); /* `tostring' may create a new string */
199 return (o != LUA_NOOBJECT) && (tonumber(o) == 0); 130 access(L, index, (tostring(L, o) == 0), NULL, svalue(o));
200} 131}
201 132
202int lua_isstring (lua_State *L, lua_Object o) { 133size_t lua_strlen (lua_State *L, int index) {
203 UNUSED(L); 134 access(L, index, (tostring(L, o) == 0), 0, tsvalue(o)->u.s.len);
204 return (o != LUA_NOOBJECT && (ttype(o) == TAG_STRING ||
205 ttype(o) == TAG_NUMBER));
206} 135}
207 136
208int lua_isfunction (lua_State *L, lua_Object o) { 137lua_CFunction lua_tocfunction (lua_State *L, int index) {
209 return *lua_type(L, o) == 'f'; 138 access(L, index, (ttype(o) == TAG_CCLOSURE), NULL, clvalue(o)->f.c);
210} 139}
211 140
212int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) { 141void *lua_touserdata (lua_State *L, int index) {
213 UNUSED(L); 142 access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value);
214 if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
215 return (o1 == o2);
216 else return luaO_equalObj(o1, o2);
217} 143}
218 144
219 145
220double lua_getnumber (lua_State *L, lua_Object obj) {
221 UNUSED(L);
222 if (obj == LUA_NOOBJECT || tonumber(obj))
223 return 0.0;
224 else return (nvalue(obj));
225}
226 146
227const char *lua_getstring (lua_State *L, lua_Object obj) { 147/*
228 luaC_checkGC(L); /* `tostring' may create a new string */ 148** push functions (C -> stack)
229 if (obj == LUA_NOOBJECT || tostring(L, obj)) 149*/
230 return NULL;
231 else return (svalue(obj));
232}
233
234size_t lua_strlen (lua_State *L, lua_Object obj) {
235 if (obj == LUA_NOOBJECT || tostring(L, obj))
236 return 0L;
237 else return (tsvalue(obj)->u.s.len);
238}
239
240void *lua_getuserdata (lua_State *L, lua_Object obj) {
241 UNUSED(L);
242 if (obj == LUA_NOOBJECT || ttype(obj) != TAG_USERDATA)
243 return NULL;
244 else return tsvalue(obj)->u.d.value;
245}
246
247lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
248 if (!lua_iscfunction(L, obj))
249 return NULL;
250 else return clvalue(obj)->f.c;
251}
252 150
253 151
254void lua_pushnil (lua_State *L) { 152void lua_pushnil (lua_State *L) {
255 ttype(L->top) = TAG_NIL; 153 ttype(L->top) = TAG_NIL;
256 incr_top; 154 api_incr_top(L);
257} 155}
258 156
157
259void lua_pushnumber (lua_State *L, double n) { 158void lua_pushnumber (lua_State *L, double n) {
260 ttype(L->top) = TAG_NUMBER; 159 ttype(L->top) = TAG_NUMBER;
261 nvalue(L->top) = n; 160 nvalue(L->top) = n;
262 incr_top; 161 api_incr_top(L);
263} 162}
264 163
164
265void lua_pushlstring (lua_State *L, const char *s, size_t len) { 165void lua_pushlstring (lua_State *L, const char *s, size_t len) {
166 luaC_checkGC(L);
266 tsvalue(L->top) = luaS_newlstr(L, s, len); 167 tsvalue(L->top) = luaS_newlstr(L, s, len);
267 ttype(L->top) = TAG_STRING; 168 ttype(L->top) = TAG_STRING;
268 incr_top; 169 api_incr_top(L);
269 luaC_checkGC(L);
270} 170}
271 171
172
272void lua_pushstring (lua_State *L, const char *s) { 173void lua_pushstring (lua_State *L, const char *s) {
273 if (s == NULL) 174 if (s == NULL)
274 lua_pushnil(L); 175 lua_pushnil(L);
@@ -276,48 +177,154 @@ void lua_pushstring (lua_State *L, const char *s) {
276 lua_pushlstring(L, s, strlen(s)); 177 lua_pushlstring(L, s, strlen(s));
277} 178}
278 179
180
279void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { 181void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
280 if (fn == NULL)
281 lua_error(L, "Lua API error - attempt to push a NULL Cfunction");
282 luaA_checkCargs(L, n);
283 luaV_Cclosure(L, fn, n);
284 luaC_checkGC(L); 182 luaC_checkGC(L);
183 luaV_Cclosure(L, fn, n);
285} 184}
286 185
186
287void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */ 187void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */
188 luaC_checkGC(L);
288 if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS) 189 if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS)
289 luaL_verror(L, "invalid tag for a userdata (%d)", tag); 190 luaL_verror(L, "invalid tag for a userdata (%d)", tag);
290 tsvalue(L->top) = luaS_createudata(L, u, tag); 191 tsvalue(L->top) = luaS_createudata(L, u, tag);
291 ttype(L->top) = TAG_USERDATA; 192 ttype(L->top) = TAG_USERDATA;
292 incr_top; 193 api_incr_top(L);
293 luaC_checkGC(L);
294} 194}
295 195
296void luaA_pushobject (lua_State *L, const TObject *o) { 196
297 *L->top = *o; 197
298 incr_top; 198/*
199** get functions (Lua -> stack)
200*/
201
202
203void lua_getglobal (lua_State *L, const char *name) {
204 luaV_getglobal(L, luaS_new(L, name), L->top++);
299} 205}
300 206
301void lua_pushobject (lua_State *L, lua_Object o) { 207
302 if (o == LUA_NOOBJECT) 208void lua_gettable (lua_State *L) {
303 lua_error(L, "Lua API error - attempt to push a NOOBJECT"); 209 luaV_gettable(L, L->top--);
304 *L->top = *o;
305 incr_top;
306} 210}
307 211
308 212
309int lua_tag (lua_State *L, lua_Object o) { 213void lua_rawget (lua_State *L) {
310 if (o == LUA_NOOBJECT) 214 if (ttype(L->top - 2) != TAG_TABLE)
311 return TAG_NIL; 215 lua_error(L, "indexed expression not a table");
312 else if (ttype(o) == TAG_USERDATA) /* to allow `old' tags (deprecated) */ 216 *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
313 return tsvalue(o)->u.d.tag; 217 L->top--;
218}
219
220
221void lua_getglobals (lua_State *L) {
222 hvalue(L->top) = L->gt;
223 ttype(L->top) = TAG_TABLE;
224 api_incr_top(L);
225}
226
227
228void lua_gettagmethod (lua_State *L, int tag, const char *event) {
229 *L->top = *luaT_gettagmethod(L, tag, event);
230 api_incr_top(L);
231}
232
233
234int lua_getref (lua_State *L, int ref) {
235 if (ref == LUA_REFNIL)
236 ttype(L->top) = TAG_NIL;
237 else if (0 <= ref && ref < L->refSize &&
238 (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
239 *L->top = L->refArray[ref].o;
314 else 240 else
315 return luaT_effectivetag(L, o); 241 return 0;
242 api_incr_top(L);
243 return 1;
244}
245
246
247void lua_newtable (lua_State *L) {
248 luaC_checkGC(L);
249 hvalue(L->top) = luaH_new(L, 0);
250 ttype(L->top) = TAG_TABLE;
251 api_incr_top(L);
316} 252}
317 253
318 254
255
256/*
257** set functions (stack -> Lua)
258*/
259
260
261void lua_setglobal (lua_State *L, const char *name) {
262 luaV_setglobal(L, luaS_new(L, name), L->top--);
263}
264
265
266void lua_settable (lua_State *L) {
267 StkId top = L->top;
268 luaV_settable(L, top-3, top);
269 L->top = top-3; /* pop table, index, and value */
270}
271
272
273void lua_rawset (lua_State *L) {
274 if (ttype(L->top-3) != TAG_TABLE)
275 lua_error(L, "indexed expression not a table");
276 *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
277 L->top -= 3;
278}
279
280
281void lua_setglobals (lua_State *L) {
282 TObject *newtable = --L->top;
283 if (ttype(newtable) != TAG_TABLE)
284 lua_error(L, "Lua API error - invalid value for global table");
285 L->gt = hvalue(newtable);
286}
287
288
289void lua_settagmethod (lua_State *L, int tag, const char *event) {
290 TObject *method = L->top - 1;
291 if (ttype(method) != TAG_NIL &&
292 ttype(method) != TAG_CCLOSURE &&
293 ttype(method) != TAG_LCLOSURE)
294 lua_error(L, "Lua API error - tag method must be a function or nil");
295 luaT_settagmethod(L, tag, event, method);
296}
297
298
299int lua_ref (lua_State *L, int lock) {
300 int ref;
301 if (ttype(L->top-1) == TAG_NIL)
302 ref = LUA_REFNIL;
303 else {
304 if (L->refFree != NONEXT) { /* is there a free place? */
305 ref = L->refFree;
306 L->refFree = L->refArray[ref].st;
307 }
308 else { /* no more free places */
309 luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
310 "reference table overflow", MAX_INT);
311 ref = L->refSize++;
312 }
313 L->refArray[ref].o = *(L->top-1);
314 L->refArray[ref].st = lock ? LOCK : HOLD;
315 }
316 L->top--;
317 return ref;
318}
319
320
321
322/*
323** miscelaneous functions
324*/
325
326
319void lua_settag (lua_State *L, int tag) { 327void lua_settag (lua_State *L, int tag) {
320 luaA_checkCargs(L, 1);
321 luaT_realtag(L, tag); 328 luaT_realtag(L, tag);
322 switch (ttype(L->top-1)) { 329 switch (ttype(L->top-1)) {
323 case TAG_TABLE: 330 case TAG_TABLE:
@@ -334,6 +341,17 @@ void lua_settag (lua_State *L, int tag) {
334} 341}
335 342
336 343
344void lua_unref (lua_State *L, int ref) {
345 if (ref >= 0) {
346 if (ref >= L->refSize || L->refArray[ref].st >= 0)
347 lua_error(L, "Lua API error - "
348 "invalid argument for function `lua_unref'");
349 L->refArray[ref].st = L->refFree;
350 L->refFree = ref;
351 }
352}
353
354
337int luaA_next (lua_State *L, const Hash *t, int i) { 355int luaA_next (lua_State *L, const Hash *t, int i) {
338 int tsize = t->size; 356 int tsize = t->size;
339 for (; i<tsize; i++) { 357 for (; i<tsize; i++) {
@@ -348,38 +366,10 @@ int luaA_next (lua_State *L, const Hash *t, int i) {
348} 366}
349 367
350 368
351int lua_next (lua_State *L, lua_Object t, int i) { 369int lua_next (lua_State *L, int index, int i) {
370 const TObject *t = Index(L, index);
352 if (ttype(t) != TAG_TABLE) 371 if (ttype(t) != TAG_TABLE)
353 lua_error(L, "Lua API error - object is not a table in `lua_next'"); 372 lua_error(L, "Lua API error - object is not a table in `lua_next'");
354 i = luaA_next(L, hvalue(t), i); 373 return luaA_next(L, hvalue(t), i);
355 top2LC(L, (i==0) ? 0 : 2);
356 return i;
357}
358
359
360
361#if LUA_DEPRECATETFUNCS
362
363/*
364** obsolete functions
365*/
366
367lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
368 lua_pushglobals(L);
369 lua_pushstring(L, name);
370 return lua_rawget(L);
371}
372
373
374void lua_rawsetglobal (lua_State *L, const char *name) {
375 lua_Object value;
376 lua_beginblock(L);
377 value = lua_pop(L);
378 lua_pushglobals(L);
379 lua_pushstring(L, name);
380 lua_pushobject(L, value);
381 lua_rawset(L);
382 lua_endblock(L);
383} 374}
384 375
385#endif