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 */
25 #include "../rfxswf.h"
30 #include "tokenizer.h"
31 #include "parser.tab.h"
35 void fixstring(char*s)
39 if(!((*s>='a' && *s<='z') || (*s>='A' && *s<='Z') ||
40 (*s>='0' && *s<='9' && !first))) {
47 static char* mkpid(const char*package)
49 char*id = malloc(strlen(package)+20);
50 strcpy(id, "package_");
58 static char* mkcid(const char*package, const char*name)
60 char*id = malloc(strlen(package)+strlen(name)+10);
67 static char* mkptr2(const char*package, const char*name)
69 if(!package[0] && !strcmp(name, "void")) {
72 char*id = malloc(strlen(package)+strlen(name)+10);
80 static char* mkid2(const char*cls, const char*member)
82 char*id = malloc(strlen(cls)+strlen(member)+10);
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)
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);
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);
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) {
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);
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;
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);
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);
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;
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);
217 fprintf(fi, "\"%s\", ", s->package);
222 fprintf(fi, "\"%s\", ", s->name);
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: {");
233 for(t=0;c->interfaces[t];t++) {
234 fprintf(fi, "%s", mkptr(c->interfaces[t]));
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
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);
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);
270 registry_classes = builtin_getclasses();
272 as3_import_abc("builtin.abc");
273 as3_import_abc("playerglobal.abc");
275 FILE*fi = fopen("builtin.c", "wb");
281 for(pass=1;pass<=3;pass++) {
283 fprintf(fi, "#include \"builtin.h\"\n");
287 fprintf(fi, "dict_t* builtin_getclasses()\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];
294 slotinfo_t*s = (slotinfo_t*)l->key;
295 //printf("%08x %s %s\n", s, s->package, s->name);
298 write_slotinfo_decl(fi, s, "");
301 write_slotinfo(fi, s, mkid(s), "");
304 fprintf(fi, " dict_put(d, &%s, &%s);\n", id, id);
305 write_initinfo(fi, s, " ");
311 fprintf(fi, " _NaN_constant.f = __builtin_nan(\"\");\n");
312 fprintf(fi, " _Infinity_constant.f = __builtin_inf();\n");
313 fprintf(fi, " return d;\n");