aboutsummaryrefslogtreecommitdiff
path: root/ltm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-05 18:15:18 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-05 18:15:18 -0200
commit592a309177edc52847b1196969ad6d49ba21f4fb (patch)
tree06add977885c012ee22cc4f105785c435b6af353 /ltm.c
parent413fc7334bf8ceaea71417d73edef15c99d3a793 (diff)
downloadlua-592a309177edc52847b1196969ad6d49ba21f4fb.tar.gz
lua-592a309177edc52847b1196969ad6d49ba21f4fb.tar.bz2
lua-592a309177edc52847b1196969ad6d49ba21f4fb.zip
tag system replaced by event tables
Diffstat (limited to 'ltm.c')
-rw-r--r--ltm.c165
1 files changed, 24 insertions, 141 deletions
diff --git a/ltm.c b/ltm.c
index ef0f89e1..5d1c83d1 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 1.80 2001/10/11 21:41:21 roberto Exp $ 2** $Id: ltm.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,8 +10,6 @@
10 10
11#include "lua.h" 11#include "lua.h"
12 12
13#include "ldo.h"
14#include "lmem.h"
15#include "lobject.h" 13#include "lobject.h"
16#include "lstate.h" 14#include "lstate.h"
17#include "lstring.h" 15#include "lstring.h"
@@ -19,161 +17,46 @@
19#include "ltm.h" 17#include "ltm.h"
20 18
21 19
22const char *const luaT_eventname[] = { /* ORDER TM */
23 "gettable", "settable", "index", "getglobal",
24 "setglobal", "add", "sub", "mul", "div",
25 "pow", "unm", "lt", "concat", "gc",
26 "function",
27 NULL
28};
29
30
31static int findevent (const char *name) {
32 int i;
33 for (i=0; luaT_eventname[i]; i++)
34 if (strcmp(luaT_eventname[i], name) == 0)
35 return i;
36 return -1; /* name not found */
37}
38
39
40static int luaI_checkevent (lua_State *L, const char *name) {
41 int e = findevent(name);
42 if (e < 0)
43 luaO_verror(L, "`%.50s' is not a valid event name", name);
44 return e;
45}
46 20
47 21const char *const luaT_typenames[] = {
48 22 "userdata", "nil", "number", "string", "table", "function"
49/* events in LUA_TNIL are all allowed, since this is used as a
50* `placeholder' for default fallbacks
51*/
52/* ORDER LUA_T, ORDER TM */
53static const lu_byte luaT_validevents[NUM_TAGS][TM_N] = {
54 {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
55 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
56 {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
57 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
58 {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
59 {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
60}; 23};
61 24
62static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
63 return (t >= NUM_TAGS) ? 1 : cast(int, luaT_validevents[t][e]);
64}
65
66 25
67void luaT_init (lua_State *L) { 26void luaT_init (lua_State *L) {
68 static const char *const typenames[NUM_TAGS] = { 27 static const char *const luaT_eventname[] = { /* ORDER TM */
69 "userdata", "nil", "number", "string", 28 "gettable", "settable", "index",
70 "table", "function" 29 "gc",
30 "add", "sub", "mul", "div",
31 "pow", "unm", "lt", "concat",
32 "call"
71 }; 33 };
72 int i; 34 int i;
73 for (i=0; i<NUM_TAGS; i++) 35 for (i=0; i<TM_N; i++) {
74 luaT_newtag(L, typenames[i], i); 36 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
75} 37 G(L)->tmname[i]->tsv.marked = FIXMARK; /* never collect these names */
76
77
78int luaT_newtag (lua_State *L, const char *name, int basictype) {
79 int tag;
80 int i;
81 TString *ts = NULL;
82 luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM,
83 MAX_INT, "tag table overflow");
84 tag = G(L)->ntag;
85 if (name) {
86 const TObject *v;
87 TObject otag;
88 ts = luaS_new(L, name);
89 v = luaH_getstr(G(L)->type2tag, ts);
90 if (ttype(v) == LUA_TNUMBER) return cast(int, nvalue(v));
91 setnvalue(&otag, tag);
92 luaH_setstr(L, G(L)->type2tag, ts, &otag);
93 } 38 }
94 for (i=0; i<TM_N; i++)
95 luaT_gettm(G(L), tag, i) = NULL;
96 G(L)->TMtable[tag].collected = NULL;
97 G(L)->TMtable[tag].name = ts;
98 G(L)->TMtable[tag].basictype = basictype;
99 G(L)->ntag++;
100 return tag;
101}
102
103
104static void checktag (lua_State *L, int tag) {
105 if (!(0 <= tag && tag < G(L)->ntag))
106 luaO_verror(L, "%d is not a valid tag", tag);
107} 39}
108 40
109 41
110int luaT_tag (const TObject *o) { 42const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
111 int t = ttype(o); 43 const TObject *tm = luaH_getstr(events, ename);
112 switch (t) { 44 if (ttype(tm) == LUA_TNIL) { /* no tag method? */
113 case LUA_TUSERDATA: return uvalue(o)->uv.tag; 45 events->flags |= (1<<event); /* cache this fact */
114 case LUA_TTABLE: return hvalue(o)->htag; 46 return NULL;
115 default: return t;
116 } 47 }
48 else return tm;
117} 49}
118 50
119 51
120const char *luaT_typename (global_State *G, const TObject *o) { 52const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
121 int t = ttype(o); 53 switch (ttype(o)) {
122 int tag;
123 TString *ts;
124 switch (t) {
125 case LUA_TUSERDATA:
126 tag = uvalue(o)->uv.tag;
127 break;
128 case LUA_TTABLE: 54 case LUA_TTABLE:
129 tag = hvalue(o)->htag; 55 return fasttm(L, hvalue(o)->eventtable, event);
130 break; 56 case LUA_TUSERDATA:
131 default: 57 return fasttm(L, uvalue(o)->uv.eventtable, event);
132 tag = t;
133 }
134 ts = G->TMtable[tag].name;
135 if (ts == NULL)
136 ts = G->TMtable[t].name;
137 return getstr(ts);
138}
139
140
141LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
142 int e;
143 lua_lock(L);
144 e = luaI_checkevent(L, event);
145 checktag(L, t);
146 if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) {
147 setclvalue(L->top, luaT_gettm(G(L), t, e));
148 }
149 else
150 setnilvalue(L->top);
151 incr_top;
152 lua_unlock(L);
153}
154
155
156LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
157 int e;
158 lua_lock(L);
159 e = luaI_checkevent(L, event);
160 checktag(L, t);
161 if (!luaT_validevent(t, e))
162 luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
163 luaT_eventname[e], typenamebytag(G(L), t),
164 (t == LUA_TTABLE || t == LUA_TUSERDATA) ?
165 " with default tag" : "");
166 switch (ttype(L->top - 1)) {
167 case LUA_TNIL:
168 luaT_gettm(G(L), t, e) = NULL;
169 break;
170 case LUA_TFUNCTION:
171 luaT_gettm(G(L), t, e) = clvalue(L->top - 1);
172 break;
173 default: 58 default:
174 luaD_error(L, "tag method must be a function (or nil)"); 59 return NULL;
175 } 60 }
176 L->top--;
177 lua_unlock(L);
178} 61}
179 62