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 char*id = malloc(strlen(package)+strlen(name)+10);
77 static char* mkid2(const char*cls, const char*member)
79 char*id = malloc(strlen(cls)+strlen(member)+10);
86 #define mkid(s) ((s)?mkcid((s)->package, (s)->name):"0")
87 #define mkptr(s) ((s)?mkptr2((s)->package, (s)->name):"0")
89 static array_t*tosort=0;
90 static int compare_classes(const void*v1, const void*v2)
94 abc_class_t*c1 = array_getvalue(tosort, x1);
95 abc_class_t*c2 = array_getvalue(tosort, x2);
96 int i = strcmp(c1->classname->ns->name, c2->classname->ns->name);
99 return strcmp(c1->classname->name, c2->classname->name);
102 static int compare_traits(const void*v1, const void*v2)
104 trait_t* x1 = *(trait_t**)v1;
105 trait_t* x2 = *(trait_t**)v2;
106 int i = strcmp(x1->name->ns->name, x2->name->ns->name);
109 return strcmp(x1->name->name, x2->name->name);
112 dict_t* builtin_getclasses()
114 return dict_new2(&slotinfo_type);
117 extern dict_t*registry_classes;
119 char*mktype(slotinfo_t*s)
121 if(s->kind == INFOTYPE_CLASS) {
122 return "classinfo_t";
123 } else if(s->kind == INFOTYPE_METHOD) {
124 return "methodinfo_t";
125 } else if(s->kind == INFOTYPE_VAR) {
131 void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix);
133 void write_slotinfo_decl(FILE*fi, slotinfo_t*s, char*prefix)
135 fprintf(fi, "%s", prefix);
137 fprintf(fi, "static %s %s;\n", mktype(s), id);
139 if(s->kind == INFOTYPE_CLASS) {
140 classinfo_t*c = (classinfo_t*)s;
141 dict_t*d = &c->members;
143 for(t=0;t<d->hashsize;t++) {
144 dictentry_t*l = d->slots[t];
146 slotinfo_t*s2 = (slotinfo_t*)l->data;
147 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 fprintf(fi, "%s", prefix);
159 dict_t*d = &c->members;
160 fprintf(fi, "dict_init2(&%s.members, &memberinfo_type, %d);\n", id, d->hashsize);
162 for(t=0;t<d->hashsize;t++) {
163 dictentry_t*l = d->slots[t];
165 slotinfo_t*s2 = (slotinfo_t*)l->data;
166 fprintf(fi, "%s", prefix);
167 char*id2 = mkid2(id, s2->name);
168 fprintf(fi, "dict_put(&%s.members, &%s, &%s);\n", id, id2,id2);
175 void write_constant(FILE*fi, constant_t*value, char*id, char*prefix)
177 if(NS_TYPE(value->type)) {
178 fprintf(fi, "%s", prefix);
179 fprintf(fi, "static namespace_t %s_constant_ns = {0x%02x, \"%s\"};\n", id, value->ns->access, value->ns->name);
180 } else if(value->type == CONSTANT_STRING) {
181 fprintf(fi, "%s", prefix);
182 fprintf(fi, "static string_t %s_constant_s = {\"%s\", %d};\n", id, value->s->str, value->s->len);
184 fprintf(fi, "%s", prefix);
185 fprintf(fi, "static constant_t %s_constant = ", id);
186 fprintf(fi, "{type: %d", value->type);
187 if(NS_TYPE(value->type)) {
188 fprintf(fi, ", &%s_constant_ns", id);
189 } else if(value->type == CONSTANT_INT) {
190 fprintf(fi, ",i: %d,", value->type);
191 } else if(value->type == CONSTANT_UINT) {
192 fprintf(fi, ",u: %u", value->u);
193 } else if(value->type == CONSTANT_FLOAT) {
194 if(!isnan(value->f) && !isinf(value->f))
195 fprintf(fi, ", %f", value->f);
196 } else if(value->type == CONSTANT_STRING) {
197 fprintf(fi, ", &%s_constant_s", id);
202 void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix)
204 if(s->kind == INFOTYPE_VAR) {
205 varinfo_t*v = (varinfo_t*)s;
207 write_constant(fi, v->value, id, prefix);
210 fprintf(fi, "%s", prefix);
211 fprintf(fi, "static %s %s = {", mktype(s), id);
212 fprintf(fi, "0x%02x, 0x%02x, 0x%02x, 0x%02x, ", s->kind, s->subtype, s->flags, s->access);
214 fprintf(fi, "\"%s\", ", s->package);
219 fprintf(fi, "\"%s\", ", s->name);
223 fprintf(fi, "%d, ", s->slot);
225 if(s->kind == INFOTYPE_CLASS) {
226 classinfo_t*c = (classinfo_t*)s;
227 fprintf(fi, "%s, ", mkptr(c->superclass));
228 fprintf(fi, "interfaces: {");
230 for(t=0;c->interfaces[t];t++) {
231 fprintf(fi, "%s", mkptr(c->interfaces[t]));
234 fprintf(fi, "0}};\n");
236 if(s->kind == INFOTYPE_METHOD) {
237 methodinfo_t*m = (methodinfo_t*)s;
238 fprintf(fi, "%s, ", mkptr(m->return_type));
239 fprintf(fi, "%s, ", mkptr(m->parent));
240 fprintf(fi, "0"); // params TODO
243 if(s->kind == INFOTYPE_VAR) {
244 varinfo_t*m = (varinfo_t*)s;
245 fprintf(fi, "%s, ", mkptr(m->type));
246 fprintf(fi, "%s, ", mkptr(m->parent));
247 if(!m->value) fprintf(fi, "0");
248 else fprintf(fi, "&%s_constant", id);
252 if(s->kind == INFOTYPE_CLASS) {
253 classinfo_t*c = (classinfo_t*)s;
254 dict_t*d = &c->members;
256 for(t=0;t<d->hashsize;t++) {
257 dictentry_t*l = d->slots[t];
259 slotinfo_t*s2 = (slotinfo_t*)l->data;
260 write_slotinfo(fi, s2, mkid2(id,s2->name), prefix);
269 registry_classes = builtin_getclasses();
271 as3_import_abc("/home/kramm/c/swftools/lib/as3/builtin.abc");
272 as3_import_abc("/home/kramm/c/swftools/lib/as3/playerglobal.abc");
274 FILE*fi = fopen("builtin.c", "wb");
280 for(pass=1;pass<=3;pass++) {
282 fprintf(fi, "#include \"builtin.h\"\n");
286 fprintf(fi, "dict_t* builtin_getclasses()\n");
288 fprintf(fi, " dict_t*d = dict_new2(&slotinfo_type);\n");
290 for(t=0;t<registry_classes->hashsize;t++) {
291 dictentry_t*l = registry_classes->slots[t];
293 slotinfo_t*s = (slotinfo_t*)l->key;
294 //printf("%08x %s %s\n", s, s->package, s->name);
297 write_slotinfo_decl(fi, s, "");
300 write_slotinfo(fi, s, mkid(s), "");
303 fprintf(fi, " dict_put(d, &%s, &%s);\n", id, id);
304 write_initinfo(fi, s, " ");
310 fprintf(fi, " _NaN_constant.f = __builtin_nan(\"\");\n");
311 fprintf(fi, " _Infinity_constant.f = __builtin_inf();\n");
312 fprintf(fi, " return d;\n");