3 Routines for compiling Flash2 AVM2 ABC Actionscript
5 Extension module for the rfxswf library.
6 Part of the swftools package.
8 Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
30 #include "tokenizer.h"
42 multiname_t*multiname;
43 multiname_list_t*multiname_list;
45 unsigned int number_uint;
48 struct _code_list*code_list;
52 %token<token> T_IDENTIFIER
53 %token<token> T_STRING
54 %token<token> T_REGEXP
56 %token<number_int> T_INT
57 %token<number_uint> T_UINT
58 %token<number_uint> T_BYTE
59 %token<number_uint> T_SHORT
60 %token<number_float> T_FLOAT
62 %token<token> KW_IMPLEMENTS
63 %token<token> KW_NAMESPACE
64 %token<token> KW_PACKAGE "package"
65 %token<token> KW_PROTECTED
66 %token<token> KW_PUBLIC
67 %token<token> KW_PRIVATE
68 %token<token> KW_USE "use"
69 %token<token> KW_INTERNAL
70 %token<token> KW_NEW "new"
71 %token<token> KW_NATIVE
72 %token<token> KW_FUNCTION "function"
73 %token<token> KW_FOR "for"
74 %token<token> KW_CLASS "class"
75 %token<token> KW_CONST "const"
76 %token<token> KW_SET "set"
77 %token<token> KW_STATIC
78 %token<token> KW_IMPORT "import"
79 %token<token> KW_INTERFACE "interface"
81 %token<token> KW_VAR "var"
82 %token<token> KW_DYNAMIC
83 %token<token> KW_OVERRIDE
84 %token<token> KW_FINAL
85 %token<token> KW_GET "get"
86 %token<token> KW_EXTENDS
87 %token<token> KW_FALSE "False"
88 %token<token> KW_TRUE "True"
89 %token<token> KW_BOOLEAN "Boolean"
90 %token<token> KW_UINT "uint"
91 %token<token> KW_INT "int"
92 %token<token> KW_NUMBER "Number"
93 %token<token> KW_STRING "String"
94 %token<token> KW_IS "is"
95 %token<token> KW_AS "as"
97 %token<token> T_EQEQ "=="
98 %token<token> T_LE "<="
99 %token<token> T_GE ">="
100 %token<token> T_DIVBY "/="
101 %token<token> T_MODBY "%="
102 %token<token> T_PLUSBY "+="
103 %token<token> T_MINUSBY "-="
104 %token<token> T_SHRBY ">>="
105 %token<token> T_SHLBY "<<="
106 %token<token> T_USHRBY ">>>="
107 %token<token> T_OROR "||"
108 %token<token> T_ANDAND "&&"
109 %token<token> T_COLONCOLON "::"
110 %token<token> T_MINUSMINUS "--"
111 %token<token> T_PLUSPLUS "++"
112 %token<token> T_DOTDOT ".."
113 %token<token> T_SHL "<<"
114 %token<token> T_USHR ">>>"
115 %token<token> T_SHR ">>"
116 %token<token> T_SEMICOLON ';'
117 %token<token> T_STAR '*'
118 %token<token> T_DOT '.'
121 %type <code> CODEPIECE CODEPIECE2
122 %type <token> PACKAGE_DECLARATION
123 %type <token> FUNCTION_DECLARATION
124 %type <code> VARIABLE_DECLARATION
125 %type <token> CLASS_DECLARATION
126 %type <token> NAMESPACE_DECLARATION
127 %type <token> INTERFACE_DECLARATION
128 %type <code> EXPRESSION
129 %type <code> MAYBEEXPRESSION
131 %type <code> CONSTANT
134 %type <token> ASSIGNMENT
136 %type <multiname> MAYBETYPE
137 %type <token> PACKAGESPEC
141 %type <token> PARAM_LIST
142 %type <token> MODIFIERS
143 %type <token> MODIFIER_LIST
144 %type <multiname_list> IMPLEMENTS_LIST
145 %type <multiname> EXTENDS
146 %type <multiname_list> EXTENDS_LIST
147 %type <multiname> PACKAGEANDCLASS
148 %type <multiname_list> PACKAGEANDCLASS_LIST
149 %type <token> MULTILEVELIDENTIFIER
150 %type <multiname> TYPE
152 %type <token> VARIABLE
153 %type <code> VAR_READ
155 %type <token> X_IDENTIFIER
156 %type <token> MODIFIER
157 %type <token> PACKAGE
158 %type <code> FUNCTIONCALL
159 %type <code_list> MAYBE_EXPRESSION_LIST EXPRESSION_LIST
161 // precendence: from low to high
162 // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000012.html
177 %nonassoc "!=" "==" "<=" '<' ">=" '>' // TODO: support "a < b < c" syntax?
193 %nonassoc T_IDENTIFIER
199 static int yyerror(char*s)
201 syntaxerror("%s", s);
203 static token_t* concat2(token_t* t1, token_t* t2)
206 int l1 = strlen(t1->text);
207 int l2 = strlen(t2->text);
208 t->text = malloc(l1+l2+1);
209 memcpy(t->text , t1->text, l1);
210 memcpy(t->text+l1, t2->text, l2);
214 static token_t* concat3(token_t* t1, token_t* t2, token_t* t3)
217 int l1 = strlen(t1->text);
218 int l2 = strlen(t2->text);
219 int l3 = strlen(t3->text);
220 t->text = malloc(l1+l2+l3+1);
221 memcpy(t->text , t1->text, l1);
222 memcpy(t->text+l1, t2->text, l2);
223 memcpy(t->text+l1+l2, t3->text, l3);
224 t->text[l1+l2+l3] = 0;
227 static char* concat3str(const char* t1, const char* t2, const char* t3)
232 char*text = malloc(l1+l2+l3+1);
233 memcpy(text , t1, l1);
234 memcpy(text+l1, t2, l2);
235 memcpy(text+l1+l2, t3, l3);
240 typedef struct _import {
244 DECLARE_LIST(import);
246 typedef struct _state {
255 import_list_t*imports;
265 static state_t* state = 0;
269 static state_list_t*state_stack=0;
271 void initialize_state()
274 NEW(state_list_t, sl);
276 state = sl->state = s;
278 state->file = abc_file_new();
279 state->file->flags &= ~ABCFILE_LAZY;
282 state->init = abc_initscript(state->file, 0, 0);
283 abc_method_body_t*m = state->init->method->body;
286 __ findpropstrict(m, "[package]::trace");
287 __ pushstring(m, "[entering global init function]");
288 __ callpropvoid(m, "[package]::trace", 1);
290 void* finalize_state()
293 syntaxerror("unexpected end of file");
295 abc_method_body_t*m = state->init->method->body;
298 __ findpropstrict(m, "[package]::trace");
299 __ pushstring(m, "[leaving global init function]");
300 __ callpropvoid(m, "[package]::trace", 1);
305 static void new_state()
308 NEW(state_list_t, sl);
311 syntaxerror("not able to start another method scope");
314 memcpy(s, state, sizeof(state_t)); //shallow copy
315 sl->next = state_stack;
321 static void old_state()
323 if(!state_stack || !state_stack->next)
324 syntaxerror("invalid nesting");
325 state_t*oldstate = state;
326 state_list_t*old = state_stack;
327 state_stack = state_stack->next;
329 state = state_stack->state;
332 static void startpackage(token_t*t)
335 syntaxerror("Packages can not be nested.");
338 char*name = t?t->text:"";
339 printf("entering package \"%s\"\n", name);
340 state->package = name;
342 static void endpackage()
344 printf("leaving package \"%s\"\n", state->package);
349 static void startclass(token_t*modifiers, token_t*name, multiname_t*extends, multiname_list_t*implements)
352 syntaxerror("inner classes now allowed");
355 state->classname = name->text;
356 printf("entering class %s\n", name->text);
358 printf(" modifiers: ");for(t=modifiers->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
359 printf(" extends: %s\n", multiname_tostring(extends));
361 multiname_list_t*mlist=0;
362 printf(" implements (%d): ", list_length(implements));
363 for(mlist=implements;mlist;mlist=mlist->next) {
364 printf("%s ", multiname_tostring(mlist->multiname));
368 char public=0,internal=0,final=0,sealed=1;
369 for(t=modifiers->tokens;t;t=t->next) {
370 if(t->token->type == KW_INTERNAL) {
371 /* the programmer is being explicit-
372 being internal is the default anyway */
374 } else if(t->token->type == KW_PUBLIC) {
376 } else if(t->token->type == KW_FINAL) {
379 syntaxerror("modifier \"%s\" not supported in class declaration", t->token->text);
383 syntaxerror("public and internal not supported at the same time.");
385 /* create the class name, together with the proper attributes */
386 multiname_t* classname = 0;
387 if(!public && !state->package)
388 classname = multiname_new(namespace_new_private(current_filename), state->classname);
389 else if(!public && state->package)
390 classname = multiname_new(namespace_new_packageinternal(state->package), state->classname);
391 else if(state->package)
392 classname = multiname_new(namespace_new_package(state->package), state->classname);
394 syntaxerror("public classes only allowed inside a package");
396 state->cls = abc_class_new(state->file, classname, extends);
397 if(final) abc_class_final(state->cls);
398 if(sealed) abc_class_sealed(state->cls);
400 for(mlist=implements;mlist;mlist=mlist->next) {
401 abc_class_add_interface(state->cls, mlist->multiname);
404 /* now write the construction code for this class */
405 int slotindex = abc_initscript_addClassTrait(state->init, classname, state->cls);
407 abc_method_body_t*m = state->init->method->body;
408 __ getglobalscope(m);
409 multiname_t*s = extends;
414 //TODO: take a look at the current scope stack, maybe
415 // we can re-use something
416 s = registry_getsuperclass(s);
421 m->code = m->code->prev->prev; // invert
424 /* continue appending after last op end */
425 while(m->code && m->code->next) m->code = m->code->next;
427 /* TODO: if this is one of *our* classes, we can also
428 do a getglobalscope/getslot <nr> (which references
429 the init function's slots) */
430 __ getlex2(m, extends);
432 __ pushscope(m); // we get a Verify Error #1107 if this is not the top scope
433 __ newclass(m,state->cls);
437 __ setslot(m, slotindex);
439 if(!globalclass && public && multiname_equals(registry_getMovieClip(),extends)) {
440 if(state->package && state->package[0]) {
441 globalclass = concat3str(state->package, ".", state->classname);
443 globalclass = strdup(state->classname);
448 static void endclass()
450 printf("leaving class %s\n", state->classname);
453 static void addimport(token_t*t)
457 list_append(state->imports, i);
459 static void print_imports()
461 import_list_t*l = state->imports;
463 printf(" import %s\n", l->import->path);
467 static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
468 token_t*params, multiname_t*type)
472 state->function = name->text;
473 printf("entering function %s\n", name->text);
475 printf(" namespace: %s\n", ns->text);
476 printf(" getset: %s\n", getset->text);
477 printf(" params: ");for(t=params->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
478 printf(" mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
479 printf(" type: %s\n", multiname_tostring(type));
482 if(!strcmp(state->classname,name->text)) {
483 state->m = abc_class_constructor(state->cls, type, 0);
485 state->m = abc_class_method(state->cls, type, name->text, 0);
487 state->vars = array_new();
488 array_append(state->vars, "this", 0);
490 __ getlocal_0(state->m);
491 __ pushscope(state->m);
493 static void endfunction()
495 printf("leaving function %s\n", state->function);
496 __ returnvoid(state->m);
500 static int newvariable(token_t*mod, token_t*varconst, token_t*name, multiname_t*type)
503 printf("defining new variable %s\n", name->text);
504 printf(" mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
505 printf(" access: ");printf("%s\n", varconst->text);
506 printf(" type: ");printf("%s\n", multiname_tostring(type));
509 syntaxerror("not allowed to defined variables outside a method");
511 int index = array_find(state->vars, name->text);
513 syntaxerror("Variable %s already defined", name->text);
515 index = array_append(state->vars, name->text, 0);
519 static token_t* empty_token()
527 void extend(token_t*list, token_t*add) {
528 list_append(list->tokens,add);
530 list->text = add->text;
532 void extend_s(token_t*list, char*seperator, token_t*add) {
533 list_append(list->tokens,add);
534 char*t1 = list->text;
540 list->text = malloc(l1+l2+l3+1);
541 strcpy(list->text, t1);
542 strcpy(list->text+l1, t2);
543 strcpy(list->text+l1+l2, t3);
544 list->text[l1+l2+l3]=0;
556 CODE: CODE CODEPIECE2 {$$=$1;}
557 CODE: CODEPIECE2 {$$=empty_token();}
559 CODEPIECE2: CODEPIECE {
561 state->m->code = code_append(state->m->code, $1);
565 CODEPIECE: ';' {/*TODO*/$$=code_new();}
566 CODEPIECE: VARIABLE_DECLARATION {$$=$1}
567 CODEPIECE: PACKAGE_DECLARATION {/*TODO*/$$=code_new();}
568 CODEPIECE: IMPORT {/*TODO*/$$=code_new();}
569 CODEPIECE: NAMESPACE_DECLARATION {/*TODO*/$$=code_new();}
570 CODEPIECE: CLASS_DECLARATION {/*TODO*/$$=code_new();}
571 CODEPIECE: INTERFACE_DECLARATION {/*TODO*/$$=code_new();}
572 CODEPIECE: FUNCTION_DECLARATION {/*TODO*/$$=code_new();}
573 CODEPIECE: EXPRESSION {/*calculate and discard*/$$=$1;$$=abc_pop($$);}
574 CODEPIECE: FOR {/*TODO*/$$=code_new();}
575 CODEPIECE: USE {/*TODO*/$$=code_new();}
576 CODEPIECE: ASSIGNMENT {/*TODO*/$$=code_new();}
578 PACKAGE_DECLARATION : "package" MULTILEVELIDENTIFIER '{' {startpackage($2)} MAYBECODE '}' {endpackage()}
579 PACKAGE_DECLARATION : "package" '{' {startpackage(0)} MAYBECODE '}' {endpackage()}
581 IMPORT : "import" PACKAGESPEC {addimport($2);}
583 TYPE : PACKAGEANDCLASS {$$=$1;}
584 | '*' {$$=registry_getanytype();}
585 | "String" {$$=registry_getstringclass();}
586 | "int" {$$=registry_getintclass();}
587 | "uint" {$$=registry_getuintclass();}
588 | "Boolean" {$$=registry_getbooleanclass();}
589 | "Number" {$$=registry_getnumberclass();}
591 MAYBETYPE: ':' TYPE {$$=$2;}
594 //FUNCTION_HEADER: NAMESPACE MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')'
595 FUNCTION_HEADER: MODIFIERS "function" GETSET T_IDENTIFIER '(' PARAMS ')'
597 FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' PARAMS ')'
598 MAYBETYPE '{' {startfunction(0,$1,$3,$4,$6,$8)} MAYBECODE '}' {endfunction()}
600 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER
601 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_IDENTIFIER
602 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_STRING
604 //NAMESPACE : {$$=empty_token();}
605 //NAMESPACE : T_IDENTIFIER {$$=$1};
607 CONSTANT : T_BYTE {$$ = abc_pushbyte(0, $1);}
608 CONSTANT : T_SHORT {$$ = abc_pushshort(0, $1);}
609 CONSTANT : T_INT {$$ = abc_pushint(0, $1);}
610 CONSTANT : T_UINT {$$ = abc_pushuint(0, $1);}
611 CONSTANT : T_FLOAT {$$ = abc_pushdouble(0, $1);}
612 CONSTANT : T_STRING {$$ = abc_pushstring(0, $1->text);}
613 CONSTANT : KW_TRUE {$$ = abc_pushtrue(0);}
614 CONSTANT : KW_FALSE {$$ = abc_pushfalse(0);}
615 CONSTANT : KW_NULL {$$ = abc_pushnull(0);}
617 VAR : "const" | "var"
622 VARIABLE_DECLARATION : MODIFIERS VAR T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION {
623 int i = newvariable($1,$2,$3,$4);
626 $$ = abc_setlocal($$, i);
629 MAYBEEXPRESSION : '=' EXPRESSION {$$=$2;}
632 EXPRESSION : E %prec prec_none /*precendence below '-x'*/ {$$ = $1;}
635 E : VAR_READ %prec T_IDENTIFIER {$$ = $1;}
636 E : NEW {$$ = abc_pushundefined(0); /* FIXME */}
637 E : T_REGEXP {$$ = abc_pushundefined(0); /* FIXME */}
653 E : '(' E ')' {$$=$2;}
656 NEW : "new" T_IDENTIFIER
657 | "new" T_IDENTIFIER '(' ')'
658 | "new" T_IDENTIFIER '(' EXPRESSION_LIST ')'
660 FUNCTIONCALL : T_IDENTIFIER '(' MAYBE_EXPRESSION_LIST ')' {
661 /* TODO: use abc_call (for calling local variables),
662 abc_callstatic (for calling own methods) */
664 $$ = abc_findproperty($$, $1->text);
666 // push parameters on stack
668 $$ = code_append($$, l->code);
671 $$ = abc_callproperty($$, $1->text, list_length($3));
674 MAYBE_EXPRESSION_LIST : {}
675 MAYBE_EXPRESSION_LIST : EXPRESSION_LIST
676 EXPRESSION_LIST : EXPRESSION {$$=list_new();list_append($$,$1);}
677 EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {list_append($$,$3);}
679 VAR_READ : T_IDENTIFIER {
680 int i = array_find(state->vars, $1->text);
682 syntaxerror("unknown variable");
683 $$ = abc_getlocal(0, i);
685 VARIABLE : T_IDENTIFIER
686 VARIABLE : VARIABLE '.' T_IDENTIFIER
687 VARIABLE : VARIABLE ".." T_IDENTIFIER // descendants
688 VARIABLE : VARIABLE "::" VARIABLE // namespace declaration
689 VARIABLE : VARIABLE "::" '[' EXPRESSION ']' // qualified expression
690 VARIABLE : VARIABLE '[' EXPRESSION ']' // unqualified expression
692 ASSIGNMENT : VARIABLE '=' EXPRESSION
693 NEW_ASSIGNMENT : "var" VARIABLE MAYBETYPE '=' EXPRESSION
695 FOR : "for" '(' NEW_ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}'
696 FOR : "for" '(' ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}'
698 USE : "use" KW_NAMESPACE T_IDENTIFIER
700 // keywords which also may be identifiers
701 X_IDENTIFIER : T_IDENTIFIER | KW_PACKAGE
703 PACKAGESPEC : PACKAGESPEC '.' PACKAGESPEC {if($1->text[0]=='*') syntaxerror("wildcard in the middle of path");
704 $$ = concat3($1,$2,$3);}
705 PACKAGESPEC : X_IDENTIFIER {$$=$1;}
706 PACKAGESPEC : '*' {$$=$1;}
708 GETSET : "get" {$$=$1;}
710 | {$$=empty_token();}
712 CLASS_DECLARATION : MODIFIERS "class" T_IDENTIFIER EXTENDS IMPLEMENTS_LIST '{' {startclass($1,$3,$4,$5);} MAYBE_DECLARATION_LIST '}' {endclass();}
713 INTERFACE_DECLARATION : MODIFIERS "interface" T_IDENTIFIER EXTENDS_LIST '{' MAYBE_IDECLARATION_LIST '}'
715 PARAMS: {$$=empty_token();}
716 PARAMS: PARAM_LIST {$$=$1;}
717 PARAM_LIST: PARAM_LIST ',' PARAM {extend($1,$3);$$=$1;}
718 PARAM_LIST: PARAM {$$=empty_token();extend($$,$1);}
719 PARAM: T_IDENTIFIER ':' TYPE {$$=$1;}
721 MODIFIERS : {$$=empty_token();}
722 MODIFIERS : MODIFIER_LIST {$$=$1}
723 MODIFIER_LIST : MODIFIER MODIFIER_LIST {extend($2,$1);$$=$2;}
724 MODIFIER_LIST : MODIFIER {$$=empty_token();extend($$,$1);}
725 MODIFIER : KW_PUBLIC | KW_PRIVATE | KW_PROTECTED | KW_STATIC | KW_DYNAMIC | KW_FINAL | KW_OVERRIDE | KW_NATIVE | KW_INTERNAL
727 DECLARATION : VARIABLE_DECLARATION
728 DECLARATION : FUNCTION_DECLARATION
730 IDECLARATION : VARIABLE_DECLARATION
731 IDECLARATION : FUNCTION_DECLARATION
733 IMPLEMENTS_LIST : {$$=list_new();}
734 IMPLEMENTS_LIST : KW_IMPLEMENTS PACKAGEANDCLASS_LIST {$$=$2;}
736 EXTENDS : {$$=registry_getobjectclass();}
737 EXTENDS : KW_EXTENDS PACKAGEANDCLASS {$$=$2;}
739 EXTENDS_LIST : {$$=list_new();}
740 EXTENDS_LIST : KW_EXTENDS PACKAGEANDCLASS_LIST {$$=$2;}
742 //IDENTIFIER_LIST : T_IDENTIFIER ',' IDENTIFIER_LIST {extend($3,$1);$$=$3;}
743 //IDENTIFIER_LIST : T_IDENTIFIER {$$=empty_token();extend($$,$1);}
745 PACKAGEANDCLASS : T_IDENTIFIER {$$ = registry_findclass(state->package, $1->text);}
746 PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {$$ = registry_findclass($1->text, $3->text);}
747 PACKAGE : X_IDENTIFIER
748 PACKAGE : PACKAGE '.' X_IDENTIFIER {$$=$1;extend_s($$,".",$3);}
750 MULTILEVELIDENTIFIER : MULTILEVELIDENTIFIER '.' X_IDENTIFIER {$$=$1;extend_s($$, ".", $3)}
751 MULTILEVELIDENTIFIER : T_IDENTIFIER {$$=$1;extend($$,$1)};
753 PACKAGEANDCLASS_LIST : PACKAGEANDCLASS {$$=list_new();list_append($$, $1);}
754 PACKAGEANDCLASS_LIST : PACKAGEANDCLASS_LIST ',' PACKAGEANDCLASS {$$=$1;list_append($$,$3);}
756 MAYBE_DECLARATION_LIST :
757 MAYBE_DECLARATION_LIST : DECLARATION_LIST
758 DECLARATION_LIST : DECLARATION
759 DECLARATION_LIST : DECLARATION_LIST DECLARATION
761 MAYBE_IDECLARATION_LIST :
762 MAYBE_IDECLARATION_LIST : IDECLARATION_LIST
763 IDECLARATION_LIST : IDECLARATION
764 IDECLARATION_LIST : IDECLARATION_LIST FUNCTION_HEADER
767 // 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
768 // syntactic keywords: each get set namespace include dynamic final native override static