kdtree code cleanup
[swftools.git] / lib / as3 / mklib.c
blobe604d0300254512e161b8ae72b030790038be603
1 /* mklib.c
3 File to generate builtin.c
5 Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <memory.h>
25 #include "../rfxswf.h"
26 #include "../os.h"
27 #include "../q.h"
28 #include "pool.h"
29 #include "files.h"
30 #include "tokenizer.h"
31 #include "parser.tab.h"
32 #include "parser.h"
33 #include "import.h"
35 void fixstring(char*s)
37 char first=1;
38 for(;*s;s++) {
39 if(!((*s>='a' && *s<='z') || (*s>='A' && *s<='Z') ||
40 (*s>='0' && *s<='9' && !first))) {
41 *s = '_';
43 first = 0;
47 static char* mkpid(const char*package)
49 char*id = malloc(strlen(package)+20);
50 strcpy(id, "package_");
51 if(!*package)
52 strcat(id, "global");
53 else
54 strcat(id, package);
55 fixstring(id);
56 return id;
58 static char* mkcid(const char*package, const char*name)
60 char*id = malloc(strlen(package)+strlen(name)+10);
61 strcpy(id, package);
62 strcat(id, "_");
63 strcat(id, name);
64 fixstring(id);
65 return id;
67 static char* mkptr2(const char*package, const char*name)
69 if(!package[0] && !strcmp(name, "void")) {
70 return "&voidclass";
72 char*id = malloc(strlen(package)+strlen(name)+10);
73 strcpy(id, "&");
74 strcat(id, package);
75 strcat(id, "_");
76 strcat(id, name);
77 fixstring(id+1);
78 return id;
80 static char* mkid2(const char*cls, const char*member)
82 char*id = malloc(strlen(cls)+strlen(member)+10);
83 strcpy(id, cls);
84 strcat(id, "_");
85 strcat(id, member);
86 fixstring(id);
87 return id;
89 #define mkid(s) ((s)?mkcid((s)->package, (s)->name):"0")
90 #define mkptr(s) ((s)?mkptr2((s)->package, (s)->name):"0")
92 static array_t*tosort=0;
93 static int compare_classes(const void*v1, const void*v2)
95 int x1 = *(int*)v1;
96 int x2 = *(int*)v2;
97 abc_class_t*c1 = array_getvalue(tosort, x1);
98 abc_class_t*c2 = array_getvalue(tosort, x2);
99 int i = strcmp(c1->classname->ns->name, c2->classname->ns->name);
100 if(i)
101 return i;
102 return strcmp(c1->classname->name, c2->classname->name);
105 static int compare_traits(const void*v1, const void*v2)
107 trait_t* x1 = *(trait_t**)v1;
108 trait_t* x2 = *(trait_t**)v2;
109 int i = strcmp(x1->name->ns->name, x2->name->ns->name);
110 if(i)
111 return i;
112 return strcmp(x1->name->name, x2->name->name);
115 dict_t* builtin_getclasses()
117 return dict_new2(&slotinfo_type);
120 extern dict_t*registry_classes;
122 char*mktype(slotinfo_t*s)
124 if(s->kind == INFOTYPE_CLASS) {
125 return "classinfo_t";
126 } else if(s->kind == INFOTYPE_METHOD) {
127 return "methodinfo_t";
128 } else if(s->kind == INFOTYPE_VAR) {
129 return "varinfo_t";
131 return "**ERROR**";
134 void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix);
136 void write_slotinfo_decl(FILE*fi, slotinfo_t*s, char*prefix)
138 fprintf(fi, "%s", prefix);
139 char*id = mkid(s);
140 fprintf(fi, "static %s %s;\n", mktype(s), id);
142 if(s->kind == INFOTYPE_CLASS) {
143 classinfo_t*c = (classinfo_t*)s;
144 dict_t*d = &c->members;
145 DICT_ITERATE_DATA(d, slotinfo_t*, s1) {
146 fprintf(fi, "static %s %s;\n", mktype(s1), mkid2(id, s1->name));
148 DICT_ITERATE_DATA(d, slotinfo_t*, s2) {
149 fprintf(fi, "static %s %s;\n", mktype(s2), mkid2(id, s2->name));
153 void write_initinfo(FILE*fi, slotinfo_t*s, char*prefix)
155 if(s->kind == INFOTYPE_CLASS) {
156 classinfo_t*c = (classinfo_t*)s;
157 char*id = mkid(c);
158 dict_t*d1 = &c->members;
159 dict_t*d2 = &c->static_members;
160 fprintf(fi, "%s", prefix);
161 fprintf(fi, "dict_init2(&%s.members, &memberinfo_type, %d);\n", id, d1->hashsize);
162 fprintf(fi, "%s", prefix);
163 fprintf(fi, "dict_init2(&%s.static_members, &memberinfo_type, %d);\n", id, d2->hashsize);
164 int t;
165 DICT_ITERATE_DATA(d1,slotinfo_t*,s1) {
166 fprintf(fi, "%s", prefix);
167 char*id2 = mkid2(id, s1->name);
168 fprintf(fi, "dict_put(&%s.members, &%s, &%s);\n", id, id2, id2);
170 DICT_ITERATE_DATA(d2,slotinfo_t*,s2) {
171 fprintf(fi, "%s", prefix);
172 char*id2 = mkid2(id, s2->name);
173 fprintf(fi, "dict_put(&%s.static_members, &%s, &%s);\n", id, id2, id2);
178 void write_constant(FILE*fi, constant_t*value, char*id, char*prefix)
180 if(NS_TYPE(value->type)) {
181 fprintf(fi, "%s", prefix);
182 fprintf(fi, "static namespace_t %s_constant_ns = {0x%02x, \"%s\"};\n", id, value->ns->access, value->ns->name);
183 } else if(value->type == CONSTANT_STRING) {
184 fprintf(fi, "%s", prefix);
185 fprintf(fi, "static string_t %s_constant_s = {\"%s\", %d};\n", id, value->s->str, value->s->len);
187 fprintf(fi, "%s", prefix);
188 fprintf(fi, "static constant_t %s_constant = ", id);
189 fprintf(fi, "{type: %d", value->type);
190 if(NS_TYPE(value->type)) {
191 fprintf(fi, ", &%s_constant_ns", id);
192 } else if(value->type == CONSTANT_INT) {
193 fprintf(fi, ",i: %d,", value->type);
194 } else if(value->type == CONSTANT_UINT) {
195 fprintf(fi, ",u: %u", value->u);
196 } else if(value->type == CONSTANT_FLOAT) {
197 if(!isnan(value->f) && !isinf(value->f))
198 fprintf(fi, ", %f", value->f);
199 } else if(value->type == CONSTANT_STRING) {
200 fprintf(fi, ", &%s_constant_s", id);
202 fprintf(fi, "};\n");
205 void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix)
207 if(s->kind == INFOTYPE_VAR) {
208 varinfo_t*v = (varinfo_t*)s;
209 if(v->value) {
210 write_constant(fi, v->value, id, prefix);
213 fprintf(fi, "%s", prefix);
214 fprintf(fi, "static %s %s = {", mktype(s), id);
215 fprintf(fi, "0x%02x, 0x%02x, 0x%02x, 0x%02x, ", s->kind, s->subtype, s->flags, s->access);
216 if(s->package)
217 fprintf(fi, "\"%s\", ", s->package);
218 else
219 fprintf(fi, "0, ");
221 if(s->name)
222 fprintf(fi, "\"%s\", ", s->name);
223 else
224 fprintf(fi, "0, ");
226 fprintf(fi, "%d, ", s->slot);
228 if(s->kind == INFOTYPE_CLASS) {
229 classinfo_t*c = (classinfo_t*)s;
230 fprintf(fi, "%s, ", mkptr(c->superclass));
231 fprintf(fi, "interfaces: {");
232 int t;
233 for(t=0;c->interfaces[t];t++) {
234 fprintf(fi, "%s", mkptr(c->interfaces[t]));
235 fprintf(fi, ", ");
237 fprintf(fi, "0}};\n");
239 if(s->kind == INFOTYPE_METHOD) {
240 methodinfo_t*m = (methodinfo_t*)s;
241 fprintf(fi, "%s, ", mkptr(m->return_type));
242 fprintf(fi, "%s, ", mkptr(m->parent));
243 fprintf(fi, "0"); // params TODO
244 fprintf(fi, "};\n");
246 if(s->kind == INFOTYPE_VAR) {
247 varinfo_t*m = (varinfo_t*)s;
248 fprintf(fi, "%s, ", mkptr(m->type));
249 fprintf(fi, "%s, ", mkptr(m->parent));
250 if(!m->value) fprintf(fi, "0");
251 else fprintf(fi, "&%s_constant", id);
252 fprintf(fi, "};\n");
255 if(s->kind == INFOTYPE_CLASS) {
256 classinfo_t*c = (classinfo_t*)s;
257 dict_t*d = &c->members;
258 DICT_ITERATE_DATA(d, slotinfo_t*, s1) {
259 write_slotinfo(fi, s1, mkid2(id,s1->name), prefix);
261 d = &c->static_members;
262 DICT_ITERATE_DATA(d, slotinfo_t*, s2) {
263 write_slotinfo(fi, s2, mkid2(id,s2->name), prefix);
268 int main()
270 registry_classes = builtin_getclasses();
272 as3_import_abc("builtin.abc");
273 as3_import_abc("playerglobal.abc");
275 FILE*fi = fopen("builtin.c", "wb");
277 int t;
278 int pass;
281 for(pass=1;pass<=3;pass++) {
282 if(pass==1) {
283 fprintf(fi, "#include \"builtin.h\"\n");
284 fprintf(fi, "\n");
286 if(pass==3) {
287 fprintf(fi, "dict_t* builtin_getclasses()\n");
288 fprintf(fi, "{\n");
289 fprintf(fi, " dict_t*d = dict_new2(&slotinfo_type);\n");
291 for(t=0;t<registry_classes->hashsize;t++) {
292 dictentry_t*l = registry_classes->slots[t];
293 while(l) {
294 slotinfo_t*s = (slotinfo_t*)l->key;
295 //printf("%08x %s %s\n", s, s->package, s->name);
296 char*id = mkid(s);
297 if(pass==1) {
298 write_slotinfo_decl(fi, s, "");
300 if(pass==2) {
301 write_slotinfo(fi, s, mkid(s), "");
303 if(pass==3) {
304 fprintf(fi, " dict_put(d, &%s, &%s);\n", id, id);
305 write_initinfo(fi, s, " ");
307 l = l->next;
311 fprintf(fi, " _NaN_constant.f = __builtin_nan(\"\");\n");
312 fprintf(fi, " _Infinity_constant.f = __builtin_inf();\n");
313 fprintf(fi, " return d;\n");
314 fprintf(fi, "}\n");
315 return 0;