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");