9 %token T_COLONCOLON "::"
13 %token T_PLUSPLUS "++"
14 %token T_MINUSMINUS "--"
59 #include "tokenizer.h"
62 static int yyerror(char*s)
66 static token_t* concat2(token_t* t1, token_t* t2)
69 int l1 = strlen(t1->text);
70 int l2 = strlen(t2->text);
71 t->text = malloc(l1+l2+1);
72 memcpy(t->text , t1->text, l1);
73 memcpy(t->text+l1, t2->text, l2);
77 static token_t* concat3(token_t* t1, token_t* t2, token_t* t3)
80 int l1 = strlen(t1->text);
81 int l2 = strlen(t2->text);
82 int l3 = strlen(t3->text);
83 t->text = malloc(l1+l2+l3+1);
84 memcpy(t->text , t1->text, l1);
85 memcpy(t->text+l1, t2->text, l2);
86 memcpy(t->text+l1+l2, t3->text, l3);
87 t->text[l1+l2+l3] = 0;
91 typedef struct _import {
97 typedef struct _state {
105 import_list_t*imports;
113 static state_t* state = 0;
117 static state_list_t*state_stack=0;
119 static void initialize_state()
122 NEW(state_list_t, sl);
124 state = sl->state = s;
126 state->file = abc_file_new();
129 state->init = abc_initscript(state->file, 0, 0);
130 abc_method_body_t*m = state->init->method->body;
134 static void finalize_state()
137 syntaxerror("unexpected end of file");
139 abc_method_body_t*m = state->init->method->body;
144 static void new_state()
147 NEW(state_list_t, sl);
148 memcpy(s, state, sizeof(state_t)); //shallow copy
149 sl->next = state_stack;
155 static void old_state()
157 if(!state_stack || !state_stack->next)
158 syntaxerror("invalid nesting");
159 state_t*oldstate = state;
160 state_list_t*old = state_stack;
161 state_stack = state_stack->next;
163 state = state_stack->state;
166 static void startpackage(token_t*t)
169 syntaxerror("Packages can not be nested.");
172 char*name = t?t->text:"";
173 printf("entering package \"%s\"\n", name);
174 state->package = name;
176 static void endpackage()
178 printf("leaving package \"%s\"\n", state->package);
182 static void startclass(token_t*modifiers, token_t*name, token_t*extends, token_t*implements)
186 syntaxerror("inner classes now allowed");
189 state->classname = name->text;
190 printf("entering class %s\n", name->text);
191 printf(" modifiers: ");for(t=modifiers->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
192 printf(" extends: %s\n", extends->text);
193 printf(" implements (%d): ", list_length(implements->tokens));for(t=implements->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
195 char public=0,internal=0,final=0,sealed=1;
196 for(t=modifiers->tokens;t;t=t->next) {
197 if(t->token->type == T_INTERNAL) {
198 /* the programmer is being explicit-
199 being internal is the default anyway */
201 } else if(t->token->type == T_PUBLIC) {
203 } else if(t->token->type == T_FINAL) {
206 syntaxerror("modifier \"%s\" not supported in class declaration", t->token->text);
210 syntaxerror("public and internal not supported at the same time.");
212 /* create the class name, together with the proper attributes */
213 multiname_t* classname = 0;
214 if(!public && !state->package)
215 classname = multiname_new(namespace_new_private(current_filename), state->classname);
216 else if(!public && state->package)
217 classname = multiname_new(namespace_new_packageinternal(state->package), state->classname);
218 else if(state->package)
219 classname = multiname_new(namespace_new_package(state->package), state->classname);
221 syntaxerror("public classes only allowed inside a package");
223 /* try to find the superclass */
224 multiname_t* superclass = 0;
225 if(extends->type != T_EMPTY) {
226 superclass = registry_findclass(extends->text);
228 superclass = registry_getobjectclass();
231 state->cls = abc_class_new(state->file, classname, superclass);
232 if(final) abc_class_final(state->cls);
233 if(sealed) abc_class_sealed(state->cls);
235 for(t=implements->tokens;t;t=t->next) {
236 abc_class_add_interface(state->cls, registry_findclass(t->token->text));
239 /* now write the construction code for this class */
240 int slotindex = abc_initscript_addClassTrait(state->init, classname, state->cls);
242 abc_method_body_t*m = state->init->method->body;
243 __ getglobalscope(m);
244 multiname_t*s = superclass;
248 //TODO: take a look at the current scope stack, maybe
249 // we can re-use something
252 s = registry_getsuperclass(s);
255 /* TODO: if this is one of *our* classes, we can also
256 do a getglobalscope/getslot <nr> (which references
257 the init function's slots) */
258 __ getlex2(m, superclass);
259 __ newclass(m,state->cls);
264 __ setslot(m, slotindex);
267 static void endclass()
269 printf("leaving class %s\n", state->classname);
272 static void addimport(token_t*t)
276 list_append(state->imports, i);
278 static void print_imports()
280 import_list_t*l = state->imports;
282 printf(" import %s\n", l->import->path);
286 static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
287 token_t*params, token_t*type)
291 state->function = name->text;
292 printf("entering function %s\n", name->text);
294 printf(" namespace: %s\n", ns->text);
295 printf(" getset: %s\n", getset->text);
296 printf(" params: ");for(t=params->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
297 printf(" mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
298 printf(" type: %s\n", type->text);
301 static void endfunction()
303 printf("leaving function %s\n", state->function);
306 static int newvariable(token_t*mod, token_t*varconst, token_t*name, token_t*type)
309 printf("defining new variable %s\n", name->text);
310 printf(" mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
311 printf(" access: ");printf("%s\n", varconst->text);
312 printf(" type: ");printf("%s\n", type->text);
314 static token_t* empty_token()
322 void extend(token_t*list, token_t*add) {
323 list_append(list->tokens,add);
325 list->text = add->text;
327 void extend_s(token_t*list, char*seperator, token_t*add) {
328 list_append(list->tokens,add);
329 char*t1 = list->text;
335 list->text = malloc(l1+l2+l3+1);
336 strcpy(list->text, t1);
337 strcpy(list->text+l1, t2);
338 strcpy(list->text+l1+l2, t3);
339 list->text[l1+l2+l3]=0;
345 PROGRAM: CODE PROGRAM
349 // token_t* t = malloc(sizeof(token_t));
350 // t->text = strdup("");
351 // t->type = T_EMPTY;
355 CODE: CODE CODEPIECE {$$=$1;}
356 CODE: CODEPIECE {$$=empty_token();}
362 CODEPIECE: VARIABLE_DECLARATION {$$=$1;}
363 CODEPIECE: PACKAGE_DECLARATION
365 CODEPIECE: NAMESPACE_DECLARATION
366 CODEPIECE: CLASS_DECLARATION
367 CODEPIECE: INTERFACE_DECLARATION
368 CODEPIECE: FUNCTION_DECLARATION
369 CODEPIECE: EXPRESSION
372 CODEPIECE: ASSIGNMENT
374 PACKAGE_DECLARATION : T_PACKAGE MULTILEVELIDENTIFIER '{' {startpackage($2)} MAYBECODE '}' {endpackage()}
375 PACKAGE_DECLARATION : T_PACKAGE '{' {startpackage(0)} MAYBECODE '}' {endpackage()}
377 IMPORT : T_IMPORT PACKAGESPEC {addimport($2);}
379 TYPE : BUILTIN_TYPE | '*' | T_IDENTIFIER
380 // TODO: do we need this? all it does it is clutter up our keyword space
381 BUILTIN_TYPE : T_STRING
382 BUILTIN_TYPE : T_NUMBER
384 BUILTIN_TYPE : T_UINT
385 BUILTIN_TYPE : T_BOOLEAN
386 BUILTIN_TYPE : T_NULL
388 MAYBETYPE: ':' TYPE {$$=$2;}
389 MAYBETYPE: {$$=empty_token();}
391 //FUNCTION_HEADER: NAMESPACE MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')'
392 FUNCTION_HEADER: MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')'
394 FUNCTION_DECLARATION: MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')'
395 MAYBETYPE '{' {startfunction(0,$1,$3,$4,$6,$8)} MAYBECODE '}' {endfunction()}
397 NAMESPACE_DECLARATION : MODIFIERS T_NAMESPACE T_IDENTIFIER
398 NAMESPACE_DECLARATION : MODIFIERS T_NAMESPACE T_IDENTIFIER '=' T_IDENTIFIER
399 NAMESPACE_DECLARATION : MODIFIERS T_NAMESPACE T_IDENTIFIER '=' T_STRING
401 //NAMESPACE : {$$=empty_token();}
402 //NAMESPACE : T_IDENTIFIER {$$=$1};
406 CONSTANT : T_TRUE | T_FALSE
409 VAR : T_CONST | T_VAR
414 VARIABLE_DECLARATION : MODIFIERS VAR T_IDENTIFIER MAYBETYPE {
415 int i = newvariable($1,$2,$3,$4);
417 VARIABLE_DECLARATION : MODIFIERS VAR T_IDENTIFIER MAYBETYPE '=' EXPRESSION {
418 int i = newvariable($1,$2,$3,$4);
422 // operator prescendence:
423 // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000012.html
424 EXPRESSION : EXPRESSION '<' EXPRESSION
425 EXPRESSION : EXPRESSION '>' EXPRESSION
426 EXPRESSION : EXPRESSION "<=" EXPRESSION
427 EXPRESSION : EXPRESSION ">=" EXPRESSION
428 EXPRESSION : EXPRESSION "==" EXPRESSION
429 EXPRESSION : EXPRESSION '+' TERM
430 EXPRESSION : EXPRESSION '-' TERM
432 EXPRESSION : '-' TERM
433 TERM : TERM '*' FACTOR
434 TERM : TERM '/' FACTOR
439 FACTOR : '(' EXPRESSION ')'
442 FACTOR : FUNCTIONCALL
448 IS : EXPRESSION T_IS TYPE
449 AS : EXPRESSION T_AS TYPE
450 NEW : T_NEW T_IDENTIFIER | T_NEW T_IDENTIFIER '(' ')'
451 NEW : T_NEW T_IDENTIFIER '(' EXPRESSIONLIST ')'
453 FUNCTIONCALL : VARIABLE '(' EXPRESSIONLIST ')'
454 FUNCTIONCALL : VARIABLE '(' ')'
456 EXPRESSIONLIST : EXPRESSION
457 EXPRESSIONLIST : EXPRESSION ',' EXPRESSIONLIST
459 VARIABLE : T_IDENTIFIER
460 VARIABLE : VARIABLE '.' T_IDENTIFIER
461 VARIABLE : VARIABLE ".." T_IDENTIFIER // descendants
462 VARIABLE : VARIABLE "::" VARIABLE // namespace declaration
463 VARIABLE : VARIABLE "::" '[' EXPRESSION ']' // qualified expression
464 VARIABLE : VARIABLE '[' EXPRESSION ']' // unqualified expression
466 ASSIGNMENT : VARIABLE '=' EXPRESSION
467 NEW_ASSIGNMENT : T_VAR VARIABLE MAYBETYPE '=' EXPRESSION
469 FOR : T_FOR '(' NEW_ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}'
470 FOR : T_FOR '(' ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}'
472 USE : T_USE T_NAMESPACE T_IDENTIFIER
474 // keywords which also may be identifiers
475 X_IDENTIFIER : T_IDENTIFIER | T_PACKAGE
477 PACKAGESPEC : PACKAGESPEC '.' PACKAGESPEC {if($1->text[0]=='*') syntaxerror("wildcard in the middle of path");
478 $$ = concat3($1,$2,$3);}
479 PACKAGESPEC : X_IDENTIFIER {$$=$1;}
480 PACKAGESPEC : '*' {$$=$1;}
482 GETSET : T_GET {$$=$1;}
484 | {$$=empty_token();}
486 CLASS_DECLARATION : MODIFIERS T_CLASS T_IDENTIFIER EXTENDS IMPLEMENTS_LIST '{' {startclass($1,$3,$4,$5);} MAYBE_DECLARATION_LIST '}' {endclass();}
487 INTERFACE_DECLARATION : MODIFIERS T_INTERFACE T_IDENTIFIER EXTENDS_LIST '{' MAYBE_IDECLARATION_LIST '}'
489 PARAMS: {$$=empty_token();}
490 PARAMS: PARAM_LIST {$$=$1;}
491 PARAM_LIST: PARAM_LIST ',' PARAM {extend($1,$3);$$=$1;}
492 PARAM_LIST: PARAM {$$=empty_token();extend($$,$1);}
493 PARAM: T_IDENTIFIER ':' TYPE {$$=$1;}
495 MODIFIERS : {$$=empty_token();}
496 MODIFIERS : MODIFIER_LIST {$$=$1}
497 MODIFIER_LIST : MODIFIER MODIFIER_LIST {extend($2,$1);$$=$2;}
498 MODIFIER_LIST : MODIFIER {$$=empty_token();extend($$,$1);}
499 MODIFIER : T_PUBLIC | T_PRIVATE | T_PROTECTED | T_STATIC | T_DYNAMIC | T_FINAL | T_OVERRIDE | T_NATIVE | T_INTERNAL
501 DECLARATION : VARIABLE_DECLARATION
502 DECLARATION : FUNCTION_DECLARATION
504 IDECLARATION : VARIABLE_DECLARATION
505 IDECLARATION : FUNCTION_DECLARATION
507 IMPLEMENTS_LIST : {$$=empty_token();}
508 IMPLEMENTS_LIST : T_IMPLEMENTS MIDENTIFIER_LIST {$$=$2;}
510 EXTENDS : {$$=empty_token();}
511 EXTENDS : T_EXTENDS MULTILEVELIDENTIFIER {$$=$2;}
513 EXTENDS_LIST : {$$=empty_token();}
514 EXTENDS_LIST : T_EXTENDS MIDENTIFIER_LIST {$$=$2;}
516 //IDENTIFIER_LIST : T_IDENTIFIER ',' IDENTIFIER_LIST {extend($3,$1);$$=$3;}
517 //IDENTIFIER_LIST : T_IDENTIFIER {$$=empty_token();extend($$,$1);}
519 MULTILEVELIDENTIFIER : T_IDENTIFIER {$$=empty_token();extend($$,$1);}
520 MULTILEVELIDENTIFIER : MULTILEVELIDENTIFIER '.' X_IDENTIFIER {extend_s($1,".",$3);$$=$1;}
522 MIDENTIFIER_LIST : MULTILEVELIDENTIFIER {$$=empty_token();extend($$,$1);}
523 MIDENTIFIER_LIST : MIDENTIFIER_LIST ',' MULTILEVELIDENTIFIER {extend($1,$3);$$=$1;}
525 MAYBE_DECLARATION_LIST :
526 MAYBE_DECLARATION_LIST : DECLARATION_LIST
527 DECLARATION_LIST : DECLARATION
528 DECLARATION_LIST : DECLARATION_LIST DECLARATION
530 MAYBE_IDECLARATION_LIST :
531 MAYBE_IDECLARATION_LIST : IDECLARATION_LIST
532 IDECLARATION_LIST : IDECLARATION
533 IDECLARATION_LIST : IDECLARATION_LIST FUNCTION_HEADER
535 // keywords: as break case catch class const continue default delete do else extends false finally for function if implements import in instanceof interface internal is native new null package private protected public return super switch this throw to true try typeof use var void while with
536 // syntactic keywords: each get set namespace include dynamic final native override static
555 if(token>=32 && token<256) {
556 printf("'%c'\n", token);
558 printf("%s\n", token2string(avm2_lval));
563 int main(int argn, char*argv[])
565 //FILE*fi = fopen("/home/kramm/c/flex/text.as", "rb");
566 char*filename = "include.as";
571 add_include_dir(getcwd(buf, 512));
572 char*fullfilename = enter_file(filename, 0);
574 FILE*fi = fopen(fullfilename, "rb");
576 perror(fullfilename);
582 if(argn>2 && !strcmp(argv[2], "-lex")) {
591 memset(&swf, 0, sizeof(swf));
593 swf.frameRate = 0x2500;
594 swf.movieSize.xmin = swf.movieSize.ymin = 0;
595 swf.movieSize.xmax = 1024*20;
596 swf.movieSize.ymax = 768*20;
597 TAG*tag = swf.firstTag = swf_InsertTag(0, ST_DOABC);
598 swf_WriteABC(tag, state->file);
599 swf_InsertTag(tag, ST_END);
601 int f = open("abc.swf",O_RDWR|O_CREAT|O_TRUNC|O_BINARY,0644);
602 swf_WriteSWF(f,&swf);