tidied up grammar section
[swftools.git] / lib / as3 / parser.y
1 /* parser.lex
2
3    Routines for compiling Flash2 AVM2 ABC Actionscript
4
5    Extension module for the rfxswf library.
6    Part of the swftools package.
7
8    Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
9  
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.
14
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.
19
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 */
23 %{
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include "abc.h"
28 #include "pool.h"
29 #include "files.h"
30 #include "tokenizer.h"
31 #include "registry.h"
32 #include "code.h"
33 #include "opcodes.h"
34
35 %}
36
37 //%glr-parser
38 //%expect-rr 1
39 %error-verbose
40
41 %union tokenunion {
42     tokenptr_t token;
43
44     class_signature_t*class_signature;
45     class_signature_list_t*class_signature_list;
46
47     int number_int;
48     unsigned int number_uint;
49     double number_float;
50     code_t*code;
51     typedcode_t value;
52     typedcode_list_t*value_list;
53     param_t* param;
54     param_list_t* param_list;
55     writeable_t writeable;
56     char*string;
57 }
58
59
60 %token<token> T_IDENTIFIER
61 %token<string> T_STRING
62 %token<token> T_REGEXP
63 %token<token> T_EMPTY
64 %token<number_int> T_INT
65 %token<number_uint> T_UINT
66 %token<number_uint> T_BYTE
67 %token<number_uint> T_SHORT
68 %token<number_float> T_FLOAT
69
70 %token<token> KW_IMPLEMENTS
71 %token<token> KW_NAMESPACE "namespace"
72 %token<token> KW_PACKAGE "package"
73 %token<token> KW_PROTECTED
74 %token<token> KW_PUBLIC
75 %token<token> KW_PRIVATE
76 %token<token> KW_USE "use"
77 %token<token> KW_INTERNAL
78 %token<token> KW_NEW "new"
79 %token<token> KW_NATIVE
80 %token<token> KW_FUNCTION "function"
81 %token<token> KW_FOR "for"
82 %token<token> KW_CLASS "class"
83 %token<token> KW_CONST "const"
84 %token<token> KW_SET "set"
85 %token<token> KW_STATIC
86 %token<token> KW_IMPORT "import"
87 %token<token> KW_RETURN "return"
88 %token<token> KW_INTERFACE "interface"
89 %token<token> KW_NULL
90 %token<token> KW_VAR "var"
91 %token<token> KW_DYNAMIC
92 %token<token> KW_OVERRIDE
93 %token<token> KW_FINAL
94 %token<token> KW_GET "get"
95 %token<token> KW_EXTENDS
96 %token<token> KW_FALSE "false"
97 %token<token> KW_TRUE "true"
98 %token<token> KW_BOOLEAN "Boolean"
99 %token<token> KW_UINT "uint"
100 %token<token> KW_INT "int"
101 %token<token> KW_WHILE "while"
102 %token<token> KW_NUMBER "Number"
103 %token<token> KW_STRING "String"
104 %token<token> KW_IF "if"
105 %token<token> KW_ELSE  "else"
106 %token<token> KW_BREAK   "break"
107 %token<token> KW_IS "is"
108 %token<token> KW_AS "as"
109
110 %token<token> T_EQEQ "=="
111 %token<token> T_EQEQEQ "==="
112 %token<token> T_NE "!="
113 %token<token> T_LE "<="
114 %token<token> T_GE ">="
115 %token<token> T_DIVBY "/=" 
116 %token<token> T_MODBY "%="
117 %token<token> T_PLUSBY "+=" 
118 %token<token> T_MINUSBY "-="
119 %token<token> T_SHRBY ">>="
120 %token<token> T_SHLBY "<<="
121 %token<token> T_USHRBY ">>>="
122 %token<token> T_OROR "||"
123 %token<token> T_ANDAND "&&"
124 %token<token> T_COLONCOLON "::"
125 %token<token> T_MINUSMINUS "--"
126 %token<token> T_PLUSPLUS "++"
127 %token<token> T_DOTDOT ".."
128 %token<token> T_SHL "<<"
129 %token<token> T_USHR ">>>"
130 %token<token> T_SHR ">>"
131 %token<token> T_SEMICOLON ';'
132 %token<token> T_STAR '*'
133 %token<token> T_DOT '.'
134
135 %type <code> CODE
136 %type <code> CODEPIECE
137 %type <code> CODEBLOCK MAYBECODE
138 %type <token> PACKAGE_DECLARATION
139 %type <token> FUNCTION_DECLARATION
140 %type <code> VARIABLE_DECLARATION
141 %type <token> CLASS_DECLARATION
142 %type <token> NAMESPACE_DECLARATION
143 %type <token> INTERFACE_DECLARATION
144 %type <code> VOIDEXPRESSION
145 %type <value> EXPRESSION
146 %type <value> MAYBEEXPRESSION
147 %type <value> E
148 %type <writeable> LH
149 %type <value> CONSTANT
150 %type <code> FOR IF WHILE MAYBEELSE BREAK RETURN
151 %type <token> USE_NAMESPACE
152 %type <code> ASSIGNMENT FOR_INIT
153 %type <token> IMPORT
154 %type <class_signature> MAYBETYPE
155 %type <token> GETSET
156 %type <param> PARAM
157 %type <param_list> PARAM_LIST
158 %type <param_list> MAYBE_PARAM_LIST
159 %type <token> MODIFIERS
160 %type <token> MODIFIER_LIST
161 %type <class_signature_list> IMPLEMENTS_LIST
162 %type <class_signature> EXTENDS
163 %type <class_signature_list> EXTENDS_LIST
164 %type <class_signature> PACKAGEANDCLASS
165 %type <class_signature_list> PACKAGEANDCLASS_LIST
166 %type <token> MULTILEVELIDENTIFIER
167 %type <class_signature> TYPE
168 %type <token> VAR
169 //%type <token> VARIABLE
170 %type <value> VAR_READ
171 %type <value> NEW
172 %type <token> X_IDENTIFIER
173 %type <token> MODIFIER
174 %type <token> PACKAGE
175 %type <value> FUNCTIONCALL
176 %type <value_list> MAYBE_EXPRESSION_LIST EXPRESSION_LIST MAYBE_PARAM_VALUES
177
178 // precedence: from low to high
179 // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000012.html
180
181 %left prec_none
182 %right '?' ':'
183 %nonassoc '='
184 %nonassoc "/=" "%="
185 %nonassoc "+=" "-="
186 %nonassoc ">>="
187 %nonassoc "<<="
188 %nonassoc ">>>="
189 %nonassoc "||"
190 %nonassoc "&&"
191 %nonassoc '|'
192 %nonassoc '^'
193 %nonassoc '&'
194 %nonassoc "!=" "==" "===" "<=" '<' ">=" '>' // TODO: support "a < b < c" syntax?
195 %nonassoc "is"
196 %left '-'
197 %left '+'
198 %left "<<"
199 %left ">>>"
200 %left ">>"
201 %left '%'
202 %left '/'
203 %left '*'
204 %left '!'
205 %left '~'
206 %left "--" "++"
207 %left '['
208 %nonassoc "as"
209 %left '.' ".." "::"
210 %nonassoc T_IDENTIFIER
211 %left below_semicolon
212 %left ';'
213 %nonassoc "else"
214 %left '('
215 %left prec_highest
216
217      
218 %{
219
220 static int yyerror(char*s)
221 {
222    syntaxerror("%s", s); 
223 }
224 static token_t* concat2(token_t* t1, token_t* t2)
225 {
226     NEW(token_t,t);
227     int l1 = strlen(t1->text);
228     int l2 = strlen(t2->text);
229     t->text = malloc(l1+l2+1);
230     memcpy(t->text   , t1->text, l1);
231     memcpy(t->text+l1, t2->text, l2);
232     t->text[l1+l2] = 0;
233     return t;
234 }
235 static token_t* concat3(token_t* t1, token_t* t2, token_t* t3)
236 {
237     NEW(token_t,t);
238     int l1 = strlen(t1->text);
239     int l2 = strlen(t2->text);
240     int l3 = strlen(t3->text);
241     t->text = malloc(l1+l2+l3+1);
242     memcpy(t->text   , t1->text, l1);
243     memcpy(t->text+l1, t2->text, l2);
244     memcpy(t->text+l1+l2, t3->text, l3);
245     t->text[l1+l2+l3] = 0;
246     return t;
247 }
248 static char* concat3str(const char* t1, const char* t2, const char* t3)
249 {
250     int l1 = strlen(t1);
251     int l2 = strlen(t2);
252     int l3 = strlen(t3);
253     char*text = malloc(l1+l2+l3+1);
254     memcpy(text   , t1, l1);
255     memcpy(text+l1, t2, l2);
256     memcpy(text+l1+l2, t3, l3);
257     text[l1+l2+l3] = 0;
258     return text;
259 }
260
261 typedef struct _import {
262     char*package;
263 } import_t;
264
265 DECLARE_LIST(import);
266
267 typedef struct _state {
268     abc_file_t*file;
269     abc_script_t*init;
270
271     int level;
272
273     char*package;     
274     char*function;
275     /* code that needs to be executed at the start of
276        a method (like initializing local registers) */
277     code_t*initcode;
278
279     abc_method_body_t*m;
280     
281     import_list_t*wildcard_imports;
282     dict_t*imports;
283     char has_own_imports;
284    
285     /* class data */
286     char*classname;
287     abc_class_t*cls;
288
289     array_t*vars;
290     int local_var_base;
291 } state_t;
292
293 static state_t* state = 0;
294
295 DECLARE_LIST(state);
296
297 #define MULTINAME(m,x) multiname_t m;namespace_t m##_ns;registry_fill_multiname(&m, &m##_ns, x);
298
299 static state_list_t*state_stack=0;
300
301 static void new_state()
302 {
303     NEW(state_t, s);
304     NEW(state_list_t, sl);
305
306     state_t*oldstate = state;
307     if(state)
308         memcpy(s, state, sizeof(state_t)); //shallow copy
309     sl->next = state_stack;
310     sl->state = s;
311     if(oldstate) {
312         s->local_var_base = array_length(oldstate->vars) + oldstate->local_var_base;
313     }
314     if(!s->imports) {
315         s->imports = dict_new();
316     }
317     state_stack = sl;
318     state = s;
319     state->level++;
320     state->vars = array_new();
321     state->initcode = 0;
322     state->has_own_imports = 0;
323 }
324 static void state_has_imports()
325 {
326     state->wildcard_imports = list_clone(state->wildcard_imports);
327     state->imports = dict_clone(state->imports);
328     state->has_own_imports = 1;
329 }
330
331 static void old_state()
332 {
333     if(!state_stack || !state_stack->next)
334         syntaxerror("invalid nesting");
335     state_t*oldstate = state;
336     state_list_t*old = state_stack;
337     state_stack = state_stack->next;
338     free(old);
339     state = state_stack->state;
340     /*if(state->initcode) {
341         printf("residual initcode\n");
342         code_dump(state->initcode, 0, 0, "", stdout);
343     }*/
344     if(oldstate->has_own_imports) {
345         list_free(oldstate->wildcard_imports);
346         dict_destroy(oldstate->imports);oldstate->imports=0;
347     }
348     state->initcode = code_append(state->initcode, oldstate->initcode);
349 }
350 void initialize_state()
351 {
352     new_state();
353
354     state->file = abc_file_new();
355     state->file->flags &= ~ABCFILE_LAZY;
356     
357     state->init = abc_initscript(state->file, 0, 0);
358     abc_method_body_t*m = state->init->method->body;
359     __ getlocal_0(m);
360     __ pushscope(m);
361     __ findpropstrict(m, "[package]::trace");
362     __ pushstring(m, "[entering global init function]");
363     __ callpropvoid(m, "[package]::trace", 1);
364 }
365 void* finalize_state()
366 {
367     if(state->level!=1) {
368         syntaxerror("unexpected end of file");
369     }
370     abc_method_body_t*m = state->init->method->body;
371     //__ popscope(m);
372     
373     __ findpropstrict(m, "[package]::trace");
374     __ pushstring(m, "[leaving global init function]");
375     __ callpropvoid(m, "[package]::trace", 1);
376     __ returnvoid(m);
377     return state->file;
378 }
379
380
381 static void startpackage(token_t*t) 
382 {
383     if(state->package) {
384         syntaxerror("Packages can not be nested."); 
385     } 
386     new_state();
387     char*name = t?t->text:"";
388     /*printf("entering package \"%s\"\n", name);*/
389     state->package = name;
390 }
391 static void endpackage()
392 {
393     /*printf("leaving package \"%s\"\n", state->package);*/
394     old_state();
395 }
396
397 char*globalclass=0;
398 static void startclass(token_t*modifiers, token_t*name, class_signature_t*extends, class_signature_list_t*implements, char interface)
399 {
400     if(state->cls) {
401         syntaxerror("inner classes now allowed"); 
402     }
403     new_state();
404     state->classname = name->text;
405
406     token_list_t*t=0;
407     class_signature_list_t*mlist=0;
408     /*printf("entering class %s\n", name->text);
409     printf("  modifiers: ");for(t=modifiers->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
410     if(extends) 
411         printf("  extends: %s.%s\n", extends->package, extends->name);
412     printf("  implements (%d): ", list_length(implements));
413     for(mlist=implements;mlist;mlist=mlist->next)  {
414         printf("%s ", mlist->class_signature?mlist->class_signature->name:0);
415     }
416     printf("\n");
417     */
418
419     char public=0,internal=0,final=0,sealed=1;
420     for(t=modifiers->tokens;t;t=t->next) {
421         if(t->token->type == KW_INTERNAL) {
422             /* the programmer is being explicit- 
423                being internal is the default anyway */
424             internal = 1;
425         } else if(t->token->type == KW_PUBLIC) {
426             public = 1;
427         } else if(t->token->type == KW_FINAL) {
428             final = 1;
429         } else {
430             syntaxerror("modifier \"%s\" not supported in class declaration", t->token->text);
431         }
432     }
433     if(public&&internal)
434         syntaxerror("public and internal not supported at the same time.");
435
436     /* create the class name, together with the proper attributes */
437     int access=0;
438     char*package=0;
439
440     if(!public && !state->package) {
441         access = ACCESS_PRIVATE; package = current_filename;
442     } else if(!public && state->package) {
443         access = ACCESS_PACKAGEINTERNAL; package = state->package;
444     } else if(state->package) {
445         access = ACCESS_PACKAGE; package = state->package;
446     } else {
447         syntaxerror("public classes only allowed inside a package");
448     }
449
450     if(registry_findclass(package, state->classname)) {
451         syntaxerror("Package \"%s\" already contains a class called \"%s\"", package, state->classname);
452     }
453     
454     class_signature_t* classname = class_signature_register(access, package, state->classname);
455
456     MULTINAME(classname2,classname);
457     
458     multiname_t*extends2 = sig2mname(extends);
459
460     state->cls = abc_class_new(state->file, &classname2, extends2);
461     if(final) abc_class_final(state->cls);
462     if(sealed) abc_class_sealed(state->cls);
463     if(interface) abc_class_interface(state->cls);
464
465     for(mlist=implements;mlist;mlist=mlist->next) {
466         MULTINAME(m, mlist->class_signature);
467         abc_class_add_interface(state->cls, &m);
468     }
469
470     /* now write the construction code for this class */
471     int slotindex = abc_initscript_addClassTrait(state->init, &classname2, state->cls);
472
473     abc_method_body_t*m = state->init->method->body;
474     __ getglobalscope(m);
475     class_signature_t*s = extends;
476
477     int count=0;
478     
479     while(s) {
480         //TODO: take a look at the current scope stack, maybe 
481         //      we can re-use something
482         s = s->superclass;
483         if(!s) 
484         break;
485        
486         multiname_t*s2 = sig2mname(s);
487         __ getlex2(m, s2);
488         multiname_destroy(s2);
489
490         __ pushscope(m);
491         m->code = m->code->prev->prev; // invert
492         count++;
493     }
494     /* continue appending after last op end */
495     while(m->code && m->code->next) m->code = m->code->next; 
496
497     /* TODO: if this is one of *our* classes, we can also 
498              do a getglobalscope/getslot <nr> (which references
499              the init function's slots) */
500     if(extends2) {
501         __ getlex2(m, extends2);
502         __ dup(m);
503         __ pushscope(m); // we get a Verify Error #1107 if this is not the top scope
504     } else {
505         __ pushnull(m);
506     }
507     __ newclass(m,state->cls);
508     while(count--) {
509         __ popscope(m);
510     }
511     __ setslot(m, slotindex);
512
513     /* flash.display.MovieClip handling */
514     if(!globalclass && public && class_signature_equals(registry_getMovieClip(),extends)) {
515         if(state->package && state->package[0]) {
516             globalclass = concat3str(state->package, ".", state->classname);
517         } else {
518             globalclass = strdup(state->classname);
519         }
520     }
521     multiname_destroy(extends2);
522 }
523
524 static void endclass()
525 {
526     /*printf("leaving class %s\n", state->classname);*/
527     old_state();
528 }
529 static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
530                           param_list_t*params, class_signature_t*type)
531 {
532     token_list_t*t;
533     new_state();
534     state->function = name->text;
535     
536     /*printf("entering function %s\n", name->text);
537     if(ns)
538         printf("  namespace: %s\n", ns->text);
539     printf("  getset: %s\n", getset->text);
540     printf("  params: ");for(t=params->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
541     printf("  mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
542     if(type)
543         printf("  type: %s.%s\n", type->package, type->name);
544     print_imports();*/
545     
546     if(state->m) {
547         syntaxerror("not able to start another method scope");
548     }
549
550     multiname_t*type2 = sig2mname(type);
551
552     if(!strcmp(state->classname,name->text)) {
553         state->m = abc_class_constructor(state->cls, type2, 0);
554     } else {
555         state->m = abc_class_method(state->cls, type2, name->text, 0);
556     }
557     param_list_t*p;
558     for(p=params;p;p=p->next) {
559         multiname_t*m = sig2mname(p->param->type);
560         list_append(state->m->method->parameters, m);
561     }
562
563     /* state->vars is initialized by state_new */
564     array_append(state->vars, "this", 0);
565     for(p=params;p;p=p->next) {
566         array_append(state->vars, p->param->name, 0);
567     }
568
569     __ getlocal_0(state->m);
570     __ pushscope(state->m);
571
572     multiname_destroy(type2);
573 }
574 static void endfunction()
575 {
576     /*printf("leaving function %s\n", state->function);*/
577     __ returnvoid(state->m);
578
579     old_state();
580 }
581
582
583 static token_t* empty_token()
584 {
585     NEW(token_t,t);
586     t->type=T_EMPTY;
587     t->text=0;
588     return t;
589 }
590
591 void extend(token_t*list, token_t*add) {
592     list_append(list->tokens,add);
593     if(!list->text)
594         list->text = add->text;
595 }
596 void extend_s(token_t*list, char*seperator, token_t*add) {
597     list_append(list->tokens,add);
598     char*t1 = list->text;
599     char*t2 = seperator;
600     char*t3 = add->text;
601     int l1 = strlen(t1);
602     int l2 = strlen(t2);
603     int l3 = strlen(t3);
604     list->text = malloc(l1+l2+l3+1);
605     strcpy(list->text, t1);
606     strcpy(list->text+l1, t2);
607     strcpy(list->text+l1+l2, t3);
608     list->text[l1+l2+l3]=0;
609 }
610
611 static int find_variable(char*name, class_signature_t**m)
612 {
613     state_list_t* s = state_stack;
614     while(s) {
615         int i = array_find(s->state->vars, name);
616         if(i>=0) {
617             if(m) {
618                 *m = array_getvalue(s->state->vars, i);
619             }
620             return i + s->state->local_var_base;
621         }
622         s = s->next;
623     }
624     syntaxerror("undefined variable: %s", name);
625
626 static char variable_exists(char*name) 
627 {
628     return array_contains(state->vars, name);
629 }
630 static int new_variable(char*name, class_signature_t*type)
631 {
632     return array_append(state->vars, name, type) + state->local_var_base;
633 }
634 code_t* killvars(code_t*c) 
635 {
636     int t;
637     for(t=0;t<state->vars->num;t++) {
638         class_signature_t*type = array_getvalue(state->vars, t);
639         //do this always, otherwise register types don't match
640         //in the verifier when doing nested loops
641         //if(!TYPE_IS_BUILTIN_SIMPLE(type)) {
642             c = abc_kill(c, t+state->local_var_base);
643         //}
644     }
645     return c;
646 }
647
648 char is_subtype_of(class_signature_t*type, class_signature_t*supertype)
649 {
650     return 1; // FIXME
651 }
652
653 void breakjumpsto(code_t*c, code_t*jump) 
654 {
655     while(c->prev) 
656         c=c->prev;
657     while(c) {
658         if(c->opcode == OPCODE___BREAK__) {
659             c->opcode = OPCODE_JUMP;
660             c->branch = jump;
661         }
662         c = c->next;
663     }
664 }
665
666 class_signature_t*join_types(class_signature_t*type1, class_signature_t*type2, char op)
667 {
668     return registry_getanytype(); // FIXME
669 }
670 code_t*converttype(code_t*c, class_signature_t*from, class_signature_t*to)
671 {
672     if(from==to)
673         return c;
674     if(!to) {
675         /*TODO: can omit this if from is zero? */
676         return abc_coerce_a(c);
677     }
678     if(TYPE_IS_NUMBER(from) && TYPE_IS_UINT(to)) {
679         MULTINAME(m, TYPE_UINT);
680         return abc_coerce2(c, &m);
681     }
682     if(TYPE_IS_NUMBER(from) && TYPE_IS_INT(to)) {
683         MULTINAME(m, TYPE_INT);
684         return abc_coerce2(c, &m);
685     }
686     return c;
687 }
688
689 code_t*defaultvalue(code_t*c, class_signature_t*type)
690 {
691     if(TYPE_IS_INT(type) || TYPE_IS_UINT(type) || TYPE_IS_FLOAT(type)) {
692        c = abc_pushbyte(c, 0);
693     } else if(TYPE_IS_BOOLEAN(type)) {
694        c = abc_pushfalse(c);
695     } else {
696        c = abc_pushnull(c);
697     }
698     return c;
699 }
700
701 %}
702
703
704 %%
705
706 /* ------------ code blocks / statements ---------------- */
707
708 PROGRAM: MAYBECODE
709
710 MAYBECODE: CODE {$$=$1;}
711 MAYBECODE:      {$$=code_new();}
712
713 CODE: CODE CODEPIECE {$$=code_append($1,$2);}
714 CODE: CODEPIECE {$$=$1;}
715
716 CODEPIECE: PACKAGE_DECLARATION   {$$=code_new();/*enters a scope*/}
717 CODEPIECE: CLASS_DECLARATION     {$$=code_new();/*enters a scope*/}
718 CODEPIECE: INTERFACE_DECLARATION {/*TODO*/$$=code_new();}
719 CODEPIECE: IMPORT                {$$=code_new();/*adds imports to current scope*/}
720 CODEPIECE: ';'                   {$$=code_new();}
721 CODEPIECE: VARIABLE_DECLARATION  {$$=$1}
722 CODEPIECE: VOIDEXPRESSION        {$$=$1}
723 CODEPIECE: FOR                   {$$=$1}
724 CODEPIECE: WHILE                 {$$=$1}
725 CODEPIECE: BREAK                 {$$=$1}
726 CODEPIECE: RETURN                {$$=$1}
727 CODEPIECE: IF                    {$$=$1}
728 CODEPIECE: ASSIGNMENT            {$$=$1}
729 CODEPIECE: NAMESPACE_DECLARATION {/*TODO*/$$=code_new();}
730 CODEPIECE: FUNCTION_DECLARATION  {/*TODO*/$$=code_new();}
731 CODEPIECE: USE_NAMESPACE         {/*TODO*/$$=code_new();}
732
733 CODEBLOCK :  '{' MAYBECODE '}' {$$=$2;}
734 CODEBLOCK :  CODEPIECE ';'             {$$=$1;}
735 CODEBLOCK :  CODEPIECE %prec below_semicolon {$$=$1;}
736
737 /* ------------ functions --------------------------- */
738
739 FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
740                       MAYBETYPE '{' {startfunction(0,$1,$3,$4,$6,$8)} MAYBECODE '}' {
741     if(!state->m) syntaxerror("internal error: undefined function");
742     state->initcode = abc_nop(state->initcode);
743     state->initcode = abc_nop(state->initcode);
744     state->initcode = abc_nop(state->initcode);
745     state->m->code = code_append(state->initcode, $11);state->initcode=0;
746     endfunction()
747 }
748
749 /* ------------ variables --------------------------- */
750
751 MAYBEEXPRESSION : '=' EXPRESSION {$$=$2;}
752                 |                {$$.c=abc_pushundefined(0);
753                                   $$.t=TYPE_ANY;
754                                  }
755
756 VAR : "const" | "var"
757 VARIABLE_DECLARATION : VAR T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION {
758     if(variable_exists($2->text))
759         syntaxerror("Variable %s already defined", $2->text);
760    
761     if(!is_subtype_of($4.t, $3)) {
762         syntaxerror("Can't convert %s to %s", $4.t->name, 
763                                               $3->name);
764     }
765
766     int index = new_variable($2->text, $3);
767     
768     if($3) {
769         if($4.c->prev || $4.c->opcode != OPCODE_PUSHUNDEFINED) {
770             $$ = $4.c;
771             $$ = converttype($$, $4.t, $3);
772             $$ = abc_setlocal($$, index);
773         } else {
774             $$ = defaultvalue(0, $3);
775             $$ = abc_setlocal($$, index);
776         }
777
778         /* push default value for type on stack */
779         state->initcode = defaultvalue(state->initcode, $3);
780         state->initcode = abc_setlocal(state->initcode, index);
781     } else {
782         /* only bother to actually set this variable if its syntax is either
783             var x:type;
784            or
785             var x=expr;
786         */
787         if($4.c->prev || $4.c->opcode != OPCODE_PUSHUNDEFINED) {
788             $$ = $4.c;
789             $$ = abc_coerce_a($$);
790             $$ = abc_setlocal($$, index);
791         } else {
792             $$ = code_new();
793         }
794     }
795     
796     /* that's the default for a local register, anyway
797         else {
798         state->initcode = abc_pushundefined(state->initcode);
799         state->initcode = abc_setlocal(state->initcode, index);
800     }*/
801     printf("variable %s -> %d (%s)\n", $2->text, index, $4.t?$4.t->name:"");
802 }
803 ASSIGNMENT :           T_IDENTIFIER '=' EXPRESSION {
804     class_signature_t*type=0;
805     int i = find_variable($1->text, &type);
806     $$ = $3.c;
807     if(!type && $3.t) {
808         // convert to "any" type, the register is untyped
809         $$ = abc_coerce_a($$);
810     } else {
811         // TODO: convert ints to strings etc.
812     }
813     $$ = abc_setlocal($$, i);
814 }
815
816 /* ------------ control flow ------------------------- */
817
818 MAYBEELSE:  %prec prec_none {$$ = code_new();}
819 MAYBEELSE: "else" CODEBLOCK {$$=$2;}
820 //MAYBEELSE: ';' "else" CODEBLOCK {$$=$3;}
821
822 IF  : "if" '(' {new_state();} EXPRESSION ')' CODEBLOCK MAYBEELSE {
823     $$ = state->initcode;state->initcode=0;
824
825     $$ = code_append($$, $4.c);
826     code_t*myjmp,*myif = $$ = abc_iffalse($$, 0);
827    
828     $$ = code_append($$, $6);
829     if($7) {
830         myjmp = $$ = abc_jump($$, 0);
831     }
832     myif->branch = $$ = abc_label($$);
833     if($7) {
834         $$ = code_append($$, $7);
835         myjmp->branch = $$ = abc_label($$);
836     }
837     
838     $$ = killvars($$);old_state();
839 }
840
841 FOR_INIT : {$$=code_new();}
842 FOR_INIT : ASSIGNMENT | VARIABLE_DECLARATION | VOIDEXPRESSION
843
844 FOR : "for" '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRESSION ')' CODEBLOCK {
845     $$ = state->initcode;state->initcode=0;
846
847     $$ = code_append($$, $4);
848     code_t*loopstart = $$ = abc_label($$);
849     $$ = code_append($$, $6.c);
850     code_t*myif = $$ = abc_iffalse($$, 0);
851     $$ = code_append($$, $10);
852     $$ = code_append($$, $8);
853     $$ = abc_jump($$, loopstart);
854     code_t*out = $$ = abc_label($$);
855     breakjumpsto($$, out);
856     myif->branch = out;
857
858     $$ = killvars($$);old_state();
859 }
860
861 WHILE : "while" '(' {new_state();} EXPRESSION ')' CODEBLOCK {
862     $$ = state->initcode;state->initcode=0;
863
864     code_t*myjmp = $$ = abc_jump($$, 0);
865     code_t*loopstart = $$ = abc_label($$);
866     $$ = code_append($$, $6);
867     myjmp->branch = $$ = abc_label($$);
868     $$ = code_append($$, $4.c);
869     $$ = abc_iftrue($$, loopstart);
870     code_t*out = $$ = abc_label($$);
871     breakjumpsto($$, out);
872
873     $$ = killvars($$);old_state();
874 }
875
876 BREAK : "break" {
877     $$ = abc___break__(0);
878 }
879
880 /* ------------ packages and imports ---------------- */
881
882 PACKAGE_DECLARATION : "package" MULTILEVELIDENTIFIER '{' {startpackage($2)} MAYBECODE '}' {endpackage()}
883 PACKAGE_DECLARATION : "package" '{' {startpackage(0)} MAYBECODE '}' {endpackage()}
884
885 PACKAGE: PACKAGE '.' X_IDENTIFIER {$$ = concat3($1,$2,$3);}
886 PACKAGE: X_IDENTIFIER             {$$=$1;}
887
888 IMPORT : "import" PACKAGE '.' X_IDENTIFIER {
889        class_signature_t*c = registry_findclass($2->text, $4->text);
890        if(!c) 
891             syntaxerror("Couldn't import %s.%s\n", $2->text, $4->text);
892        state_has_imports();
893        dict_put(state->imports, $4->text, c);
894        $$=0;
895 }
896 IMPORT : "import" PACKAGE '.' '*' {
897        NEW(import_t,i);
898        i->package = $2->text;
899        state_has_imports();
900        list_append(state->wildcard_imports, i);
901        $$=0;
902 }
903
904 /* ------------ classes and interfaces -------------- */
905
906 MODIFIERS : {$$=empty_token();}
907 MODIFIERS : MODIFIER_LIST {$$=$1}
908 MODIFIER_LIST : MODIFIER MODIFIER_LIST {extend($2,$1);$$=$2;}
909 MODIFIER_LIST : MODIFIER               {$$=empty_token();extend($$,$1);}
910 MODIFIER : KW_PUBLIC | KW_PRIVATE | KW_PROTECTED | KW_STATIC | KW_DYNAMIC | KW_FINAL | KW_OVERRIDE | KW_NATIVE | KW_INTERNAL
911
912 EXTENDS : {$$=registry_getobjectclass();}
913 EXTENDS : KW_EXTENDS PACKAGEANDCLASS {$$=$2;}
914
915 EXTENDS_LIST : {$$=list_new();}
916 EXTENDS_LIST : KW_EXTENDS PACKAGEANDCLASS_LIST {$$=$2;}
917
918 IMPLEMENTS_LIST : {$$=list_new();}
919 IMPLEMENTS_LIST : KW_IMPLEMENTS PACKAGEANDCLASS_LIST {$$=$2;}
920
921 CLASS_DECLARATION : MODIFIERS "class" T_IDENTIFIER 
922                               EXTENDS IMPLEMENTS_LIST 
923                               '{' {startclass($1,$3,$4,$5, 0);} 
924                               MAYBE_DECLARATION_LIST 
925                               '}' {endclass();}
926 INTERFACE_DECLARATION : MODIFIERS "interface" T_IDENTIFIER 
927                               EXTENDS_LIST 
928                               '{' {startclass($1,$3,0,$4,1);}
929                               MAYBE_IDECLARATION_LIST 
930                               '}' {endclass();}
931
932 /* ------------- package + class ids --------------- */
933
934 PACKAGEANDCLASS : T_IDENTIFIER {
935
936     /* try current package */
937     $$ = registry_findclass(state->package, $1->text);
938
939     /* try explicit imports */
940     dictentry_t* e = dict_get_slot(state->imports, $1->text);
941     while(e) {
942         if($$)
943             break;
944         if(!strcmp(e->key, $1->text)) {
945             $$ = (class_signature_t*)e->data;
946         }
947         e = e->next;
948     }
949
950     /* try package.* imports */
951     import_list_t*l = state->wildcard_imports;
952     while(l) {
953         if($$)
954             break;
955         //printf("does package %s contain a class %s?\n", l->import->package, $1->text);
956         $$ = registry_findclass(l->import->package, $1->text);
957         l = l->next;
958     }
959
960     /* try global package */
961     if(!$$) {
962         $$ = registry_findclass("", $1->text);
963     }
964
965     if(!$$) syntaxerror("Could not find class %s\n", $1->text);
966 }
967 PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {
968     $$ = registry_findclass($1->text, $3->text);
969     if(!$$) syntaxerror("Couldn't find class %s.%s\n", $1->text, $3->text);
970 }
971
972
973 /* ----------function calls, constructor calls ------ */
974
975 MAYBE_PARAM_VALUES :  %prec prec_none {$$=0;}
976 MAYBE_PARAM_VALUES : '(' MAYBE_EXPRESSION_LIST ')' {$$=$2}
977
978 MAYBE_EXPRESSION_LIST : {$$=0;}
979 MAYBE_EXPRESSION_LIST : EXPRESSION_LIST
980 EXPRESSION_LIST : EXPRESSION                     {$$=list_new();
981                                                   typedcode_t*t = malloc(sizeof(typedcode_t));
982                                                   *t = $1;
983                                                   list_append($$, t);}
984 EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {$$=$1;
985                                                   typedcode_t*t = malloc(sizeof(typedcode_t));
986                                                   *t = $3;
987                                                   list_append($$, t);}
988
989 NEW : "new" PACKAGEANDCLASS MAYBE_PARAM_VALUES {
990     MULTINAME(m, $2);
991     $$.c = code_new();
992     $$.c = abc_findpropstrict2($$.c, &m);
993     typedcode_list_t*l = $3;
994     int len = 0;
995     while(l) {
996         $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
997         l = l->next;
998         len ++;
999     }
1000     $$.c = abc_constructprop2($$.c, &m, len);
1001     $$.t = $2;
1002 }
1003
1004 FUNCTIONCALL : T_IDENTIFIER '(' MAYBE_EXPRESSION_LIST ')' {
1005     /* TODO: use abc_call (for calling local variables),
1006              abc_callstatic (for calling own methods) */
1007     $$.c = code_new();
1008     $$.c = abc_findpropstrict($$.c, $1->text);
1009     typedcode_list_t*l = $3;
1010     int len = 0;
1011     while(l) {
1012         $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
1013         l = l->next;
1014         len ++;
1015     }
1016     $$.c = abc_callproperty($$.c, $1->text, len);
1017     /* TODO: look up the functions's return value */
1018     $$.t = TYPE_ANY;
1019 }
1020
1021 RETURN: "return" %prec prec_none {
1022     $$ = abc_returnvoid(0);
1023 }
1024 RETURN: "return" EXPRESSION {
1025     $$ = $2.c;
1026     $$ = abc_returnvalue($$);
1027 }
1028
1029 TYPE : PACKAGEANDCLASS {$$=$1;}
1030      | '*'        {$$=registry_getanytype();}
1031      |  "String"  {$$=registry_getstringclass();}
1032      |  "int"     {$$=registry_getintclass();}
1033      |  "uint"    {$$=registry_getuintclass();}
1034      |  "Boolean" {$$=registry_getbooleanclass();}
1035      |  "Number"  {$$=registry_getnumberclass();}
1036
1037 MAYBETYPE: ':' TYPE {$$=$2;}
1038 MAYBETYPE:          {$$=0;}
1039
1040 //FUNCTION_HEADER:      NAMESPACE MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')' 
1041 FUNCTION_HEADER:      MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
1042                       MAYBETYPE
1043
1044 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER
1045 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_IDENTIFIER
1046 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_STRING
1047
1048 //NAMESPACE :              {$$=empty_token();}
1049 //NAMESPACE : T_IDENTIFIER {$$=$1};
1050
1051 CONSTANT : T_BYTE {$$.c = abc_pushbyte(0, $1);
1052                    //MULTINAME(m, registry_getintclass());
1053                    //$$.c = abc_coerce2($$.c, &m); // FIXME
1054                    $$.t = TYPE_INT;
1055                   }
1056 CONSTANT : T_SHORT {$$.c = abc_pushshort(0, $1);
1057                     $$.t = TYPE_INT;
1058                    }
1059 CONSTANT : T_INT {$$.c = abc_pushint(0, $1);
1060                   $$.t = TYPE_INT;
1061                  }
1062 CONSTANT : T_UINT {$$.c = abc_pushuint(0, $1);
1063                    $$.t = TYPE_UINT;
1064                   }
1065 CONSTANT : T_FLOAT {$$.c = abc_pushdouble(0, $1);
1066                     $$.t = TYPE_FLOAT;
1067                    }
1068 CONSTANT : T_STRING {$$.c = abc_pushstring(0, $1);
1069                      $$.t = TYPE_STRING;
1070                     }
1071 CONSTANT : KW_TRUE {$$.c = abc_pushtrue(0);
1072                     $$.t = TYPE_BOOLEAN;
1073                    }
1074 CONSTANT : KW_FALSE {$$.c = abc_pushfalse(0);
1075                      $$.t = TYPE_BOOLEAN;
1076                     }
1077 CONSTANT : KW_NULL {$$.c = abc_pushnull(0);
1078                     $$.t = TYPE_NULL;
1079                    }
1080
1081 USE_NAMESPACE : "use" "namespace" T_IDENTIFIER
1082
1083
1084 EXPRESSION : E %prec prec_none  /*precedence below '-x'*/ {$$ = $1;}
1085 VOIDEXPRESSION : E %prec prec_none {$$=$1.c;/*calculate and discard*/$$=abc_pop($$);}
1086
1087 E : CONSTANT
1088 E : VAR_READ %prec T_IDENTIFIER {$$ = $1;}
1089 E : NEW                         {$$ = $1;}
1090 E : T_REGEXP                    {$$.c = abc_pushundefined(0); /* FIXME */
1091                                  $$.t = TYPE_ANY;
1092                                 }
1093 E : FUNCTIONCALL
1094 E : E '<' E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterequals($$.c);$$.c=abc_not($$.c);
1095              $$.t = TYPE_BOOLEAN;
1096             }
1097 E : E '>' E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterthan($$.c);
1098              $$.t = TYPE_BOOLEAN;
1099             }
1100 E : E "<=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterthan($$.c);$$.c=abc_not($$.c);
1101               $$.t = TYPE_BOOLEAN;
1102              }
1103 E : E ">=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterequals($$.c);
1104               $$.t = TYPE_BOOLEAN;
1105              }
1106 E : E "==" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c);
1107               $$.t = TYPE_BOOLEAN;
1108              }
1109 E : E "===" E {$$.c = code_append($1.c,$3.c);$$.c = abc_strictequals($$.c);
1110               $$.t = TYPE_BOOLEAN;
1111              }
1112 E : E "!=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c);$$.c = abc_not($$.c);
1113               $$.t = TYPE_BOOLEAN;
1114              }
1115
1116 E : E "||" E {$$.t = join_types($1.t, $3.t, 'O');
1117               $$.c = $1.c;
1118               $$.c = converttype($$.c, $1.t, $$.t);
1119               $$.c = abc_dup($$.c);
1120               code_t*jmp = $$.c = abc_iftrue($$.c, 0);
1121               $$.c = abc_pop($$.c);
1122               $$.c = code_append($$.c,$3.c);
1123               $$.c = converttype($$.c, $1.t, $$.t);
1124               code_t*label = $$.c = abc_label($$.c);
1125               jmp->branch = label;
1126              }
1127 E : E "&&" E {$$.t = join_types($1.t, $3.t, 'A');
1128               $$.c = $1.c;
1129               $$.c = converttype($$.c, $1.t, $$.t);
1130               $$.c = abc_dup($$.c);
1131               code_t*jmp = $$.c = abc_iffalse($$.c, 0);
1132               $$.c = abc_pop($$.c);
1133               $$.c = code_append($$.c,$3.c);
1134               $$.c = converttype($$.c, $1.t, $$.t);
1135               code_t*label = $$.c = abc_label($$.c);
1136               jmp->branch = label;              
1137              }
1138
1139 E : '!' E    {$$.c=$2.c;
1140               $$.c = abc_not($$.c);
1141               $$.t = TYPE_BOOLEAN;
1142              }
1143
1144 E : E '-' E
1145 E : E '/' E
1146 E : E '+' E {$$.c = code_append($1.c,$3.c);$$.c = abc_add($$.c);$$.c=abc_coerce_a($$.c);
1147              $$.t = join_types($1.t, $3.t, '+');
1148             }
1149 E : E '%' E {$$.c = code_append($1.c,$3.c);$$.c = abc_modulo($$.c);$$.c=abc_coerce_a($$.c);
1150              $$.t = join_types($1.t, $3.t, '%');
1151             }
1152 E : E '*' E {$$.c = code_append($1.c,$3.c);$$.c = abc_multiply($$.c);$$.c=abc_coerce_a($$.c);
1153              $$.t = join_types($1.t, $3.t, '*');
1154             }
1155
1156 E : E "as" TYPE
1157 E : E "is" TYPE
1158 E : '(' E ')' {$$=$2;}
1159 E : '-' E {$$=$2;}
1160
1161 E : LH "+=" E {$$.c = $1.read;$$.c=code_append($$.c,$3.c);$$.c=abc_add($$.c);
1162                class_signature_t*type = join_types($1.type, $3.t, '+');
1163                $$.c=converttype($$.c, type, $1.type);
1164                $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1165                $$.t = $1.type;
1166               }
1167 E : LH "-=" E {$$.c = $1.read;$$.c=code_append($$.c,$3.c);$$.c=abc_add($$.c);
1168                class_signature_t*type = join_types($1.type, $3.t, '-');
1169                $$.c=converttype($$.c, type, $1.type);
1170                $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1171                $$.t = $1.type;
1172               }
1173
1174 // TODO: use inclocal where appropriate
1175 E : LH "++" {$$.c = $1.read;
1176              class_signature_t*type = $1.type;
1177              if(TYPE_IS_INT(type) || TYPE_IS_UINT(type)) {
1178                  $$.c=abc_increment_i($$.c);
1179              } else {
1180                  $$.c=abc_increment($$.c);
1181                  type = TYPE_NUMBER;
1182              }
1183              $$.c=converttype($$.c, type, $1.type);
1184              $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1185              $$.t = $1.type;
1186             }
1187 E : LH "--" {$$.c = $1.read;
1188              class_signature_t*type = $1.type;
1189              if(TYPE_IS_INT(type) || TYPE_IS_UINT(type)) {
1190                  $$.c=abc_decrement_i($$.c);
1191              } else {
1192                  $$.c=abc_decrement($$.c);
1193                  type = TYPE_NUMBER;
1194              }
1195              $$.c=converttype($$.c, type, $1.type);
1196              $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1197              $$.t = $1.type;
1198             }
1199
1200 LH: T_IDENTIFIER {
1201   int i = find_variable($1->text, &$$.type);
1202   $$.read = abc_getlocal(0, i);
1203   $$.write = abc_setlocal(0, i);
1204 }
1205
1206
1207 VAR_READ : T_IDENTIFIER {
1208     int i = find_variable($1->text, &$$.t);
1209     $$.c = abc_getlocal(0, i);
1210 }
1211
1212 //VARIABLE : T_IDENTIFIER
1213 //VARIABLE : VARIABLE '.' T_IDENTIFIER
1214 //VARIABLE : VARIABLE ".." T_IDENTIFIER // descendants
1215 //VARIABLE : VARIABLE "::" VARIABLE // namespace declaration
1216 //VARIABLE : VARIABLE "::" '[' EXPRESSION ']' // qualified expression
1217 //VARIABLE : VARIABLE '[' EXPRESSION ']' // unqualified expression
1218
1219 // keywords which also may be identifiers
1220 X_IDENTIFIER : T_IDENTIFIER | KW_PACKAGE
1221
1222 GETSET : "get" {$$=$1;}
1223        | "set" {$$=$1;}
1224        |       {$$=empty_token();}
1225
1226 MAYBE_PARAM_LIST: {$$=list_new();}
1227 MAYBE_PARAM_LIST: PARAM_LIST {$$=$1;}
1228 PARAM_LIST: PARAM_LIST ',' PARAM {$$ =$1;         list_append($$, $3);}
1229 PARAM_LIST: PARAM                {$$ = list_new();list_append($$, $1);}
1230 PARAM:  T_IDENTIFIER ':' TYPE {$$ = malloc(sizeof(param_t));
1231                                $$->name=$1->text;$$->type = $3;}
1232 PARAM:  T_IDENTIFIER          {$$ = malloc(sizeof(param_t));
1233                                $$->name=$1->text;$$->type = TYPE_ANY;}
1234
1235 DECLARATION : VARIABLE_DECLARATION
1236 DECLARATION : FUNCTION_DECLARATION
1237
1238 IDECLARATION : VARIABLE_DECLARATION
1239 IDECLARATION : FUNCTION_DECLARATION
1240
1241 //IDENTIFIER_LIST : T_IDENTIFIER ',' IDENTIFIER_LIST {extend($3,$1);$$=$3;}
1242 //IDENTIFIER_LIST : T_IDENTIFIER                     {$$=empty_token();extend($$,$1);}
1243
1244 MULTILEVELIDENTIFIER : MULTILEVELIDENTIFIER '.' X_IDENTIFIER {$$=$1;extend_s($$, ".", $3)}
1245 MULTILEVELIDENTIFIER : T_IDENTIFIER                 {$$=$1;extend($$,$1)};
1246
1247 PACKAGEANDCLASS_LIST : PACKAGEANDCLASS {$$=list_new();list_append($$, $1);}
1248 PACKAGEANDCLASS_LIST : PACKAGEANDCLASS_LIST ',' PACKAGEANDCLASS {$$=$1;list_append($$,$3);}
1249
1250 MAYBE_DECLARATION_LIST : 
1251 MAYBE_DECLARATION_LIST : DECLARATION_LIST
1252 DECLARATION_LIST : DECLARATION
1253 DECLARATION_LIST : DECLARATION_LIST DECLARATION
1254
1255 MAYBE_IDECLARATION_LIST : 
1256 MAYBE_IDECLARATION_LIST : IDECLARATION_LIST
1257 IDECLARATION_LIST : IDECLARATION
1258 IDECLARATION_LIST : IDECLARATION_LIST FUNCTION_HEADER
1259
1260 // chapter 14
1261 // 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
1262 // syntactic keywords: each get set namespace include dynamic final native override static
1263