fixed top scope element for interface instantiation
[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); count++;
491         m->code = m->code->prev->prev; // invert
492     }
493     /* continue appending after last op end */
494     while(m->code && m->code->next) m->code = m->code->next; 
495
496     /* TODO: if this is one of *our* classes, we can also 
497              do a getglobalscope/getslot <nr> (which references
498              the init function's slots) */
499     if(extends2) {
500         __ getlex2(m, extends2);
501         __ dup(m);
502         /* notice: we get a Verify Error #1107 if the top elemnt on the scope
503            stack is not the superclass */
504         __ pushscope(m);count++;
505     } else {
506         __ pushnull(m);
507         /* notice: we get a verify error #1107 if the top element on the scope 
508            stack is not the global object */
509         __ getlocal_0(m);
510         __ pushscope(m);count++;
511     }
512     __ newclass(m,state->cls);
513     while(count--) {
514         __ popscope(m);
515     }
516     __ setslot(m, slotindex);
517
518     /* flash.display.MovieClip handling */
519     if(!globalclass && public && class_signature_equals(registry_getMovieClip(),extends)) {
520         if(state->package && state->package[0]) {
521             globalclass = concat3str(state->package, ".", state->classname);
522         } else {
523             globalclass = strdup(state->classname);
524         }
525     }
526     multiname_destroy(extends2);
527 }
528
529 static void endclass()
530 {
531     /*printf("leaving class %s\n", state->classname);*/
532     old_state();
533 }
534 static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
535                           param_list_t*params, class_signature_t*type)
536 {
537     token_list_t*t;
538     new_state();
539     state->function = name->text;
540     
541     /*printf("entering function %s\n", name->text);
542     if(ns)
543         printf("  namespace: %s\n", ns->text);
544     printf("  getset: %s\n", getset->text);
545     printf("  params: ");for(t=params->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
546     printf("  mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n");
547     if(type)
548         printf("  type: %s.%s\n", type->package, type->name);
549     print_imports();*/
550     
551     if(state->m) {
552         syntaxerror("not able to start another method scope");
553     }
554
555     multiname_t*type2 = sig2mname(type);
556
557     if(!strcmp(state->classname,name->text)) {
558         state->m = abc_class_constructor(state->cls, type2, 0);
559     } else {
560         state->m = abc_class_method(state->cls, type2, name->text, 0);
561     }
562     param_list_t*p;
563     for(p=params;p;p=p->next) {
564         multiname_t*m = sig2mname(p->param->type);
565         list_append(state->m->method->parameters, m);
566     }
567
568     /* state->vars is initialized by state_new */
569     array_append(state->vars, "this", 0);
570     for(p=params;p;p=p->next) {
571         array_append(state->vars, p->param->name, 0);
572     }
573
574     __ getlocal_0(state->m);
575     __ pushscope(state->m);
576
577     multiname_destroy(type2);
578 }
579 static void endfunction()
580 {
581     /*printf("leaving function %s\n", state->function);*/
582     __ returnvoid(state->m);
583
584     old_state();
585 }
586
587
588 static token_t* empty_token()
589 {
590     NEW(token_t,t);
591     t->type=T_EMPTY;
592     t->text=0;
593     return t;
594 }
595
596 void extend(token_t*list, token_t*add) {
597     list_append(list->tokens,add);
598     if(!list->text)
599         list->text = add->text;
600 }
601 void extend_s(token_t*list, char*seperator, token_t*add) {
602     list_append(list->tokens,add);
603     char*t1 = list->text;
604     char*t2 = seperator;
605     char*t3 = add->text;
606     int l1 = strlen(t1);
607     int l2 = strlen(t2);
608     int l3 = strlen(t3);
609     list->text = malloc(l1+l2+l3+1);
610     strcpy(list->text, t1);
611     strcpy(list->text+l1, t2);
612     strcpy(list->text+l1+l2, t3);
613     list->text[l1+l2+l3]=0;
614 }
615
616 static int find_variable(char*name, class_signature_t**m)
617 {
618     state_list_t* s = state_stack;
619     while(s) {
620         int i = array_find(s->state->vars, name);
621         if(i>=0) {
622             if(m) {
623                 *m = array_getvalue(s->state->vars, i);
624             }
625             return i + s->state->local_var_base;
626         }
627         s = s->next;
628     }
629     syntaxerror("undefined variable: %s", name);
630
631 static char variable_exists(char*name) 
632 {
633     return array_contains(state->vars, name);
634 }
635 static int new_variable(char*name, class_signature_t*type)
636 {
637     return array_append(state->vars, name, type) + state->local_var_base;
638 }
639 code_t* killvars(code_t*c) 
640 {
641     int t;
642     for(t=0;t<state->vars->num;t++) {
643         class_signature_t*type = array_getvalue(state->vars, t);
644         //do this always, otherwise register types don't match
645         //in the verifier when doing nested loops
646         //if(!TYPE_IS_BUILTIN_SIMPLE(type)) {
647             c = abc_kill(c, t+state->local_var_base);
648         //}
649     }
650     return c;
651 }
652
653 char is_subtype_of(class_signature_t*type, class_signature_t*supertype)
654 {
655     return 1; // FIXME
656 }
657
658 void breakjumpsto(code_t*c, code_t*jump) 
659 {
660     while(c->prev) 
661         c=c->prev;
662     while(c) {
663         if(c->opcode == OPCODE___BREAK__) {
664             c->opcode = OPCODE_JUMP;
665             c->branch = jump;
666         }
667         c = c->next;
668     }
669 }
670
671 class_signature_t*join_types(class_signature_t*type1, class_signature_t*type2, char op)
672 {
673     return registry_getanytype(); // FIXME
674 }
675 code_t*converttype(code_t*c, class_signature_t*from, class_signature_t*to)
676 {
677     if(from==to)
678         return c;
679     if(!to) {
680         /*TODO: can omit this if from is zero? */
681         return abc_coerce_a(c);
682     }
683     if(TYPE_IS_NUMBER(from) && TYPE_IS_UINT(to)) {
684         MULTINAME(m, TYPE_UINT);
685         return abc_coerce2(c, &m);
686     }
687     if(TYPE_IS_NUMBER(from) && TYPE_IS_INT(to)) {
688         MULTINAME(m, TYPE_INT);
689         return abc_coerce2(c, &m);
690     }
691     return c;
692 }
693
694 code_t*defaultvalue(code_t*c, class_signature_t*type)
695 {
696     if(TYPE_IS_INT(type) || TYPE_IS_UINT(type) || TYPE_IS_FLOAT(type)) {
697        c = abc_pushbyte(c, 0);
698     } else if(TYPE_IS_BOOLEAN(type)) {
699        c = abc_pushfalse(c);
700     } else {
701        c = abc_pushnull(c);
702     }
703     return c;
704 }
705
706 %}
707
708
709 %%
710
711 /* ------------ code blocks / statements ---------------- */
712
713 PROGRAM: MAYBECODE
714
715 MAYBECODE: CODE {$$=$1;}
716 MAYBECODE:      {$$=code_new();}
717
718 CODE: CODE CODEPIECE {$$=code_append($1,$2);}
719 CODE: CODEPIECE {$$=$1;}
720
721 CODEPIECE: PACKAGE_DECLARATION   {$$=code_new();/*enters a scope*/}
722 CODEPIECE: CLASS_DECLARATION     {$$=code_new();/*enters a scope*/}
723 CODEPIECE: INTERFACE_DECLARATION {/*TODO*/$$=code_new();}
724 CODEPIECE: IMPORT                {$$=code_new();/*adds imports to current scope*/}
725 CODEPIECE: ';'                   {$$=code_new();}
726 CODEPIECE: VARIABLE_DECLARATION  {$$=$1}
727 CODEPIECE: VOIDEXPRESSION        {$$=$1}
728 CODEPIECE: FOR                   {$$=$1}
729 CODEPIECE: WHILE                 {$$=$1}
730 CODEPIECE: BREAK                 {$$=$1}
731 CODEPIECE: RETURN                {$$=$1}
732 CODEPIECE: IF                    {$$=$1}
733 CODEPIECE: ASSIGNMENT            {$$=$1}
734 CODEPIECE: NAMESPACE_DECLARATION {/*TODO*/$$=code_new();}
735 CODEPIECE: FUNCTION_DECLARATION  {/*TODO*/$$=code_new();}
736 CODEPIECE: USE_NAMESPACE         {/*TODO*/$$=code_new();}
737
738 CODEBLOCK :  '{' MAYBECODE '}' {$$=$2;}
739 CODEBLOCK :  CODEPIECE ';'             {$$=$1;}
740 CODEBLOCK :  CODEPIECE %prec below_semicolon {$$=$1;}
741
742 /* ------------ functions --------------------------- */
743
744 FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
745                       MAYBETYPE '{' {startfunction(0,$1,$3,$4,$6,$8)} MAYBECODE '}' {
746     if(!state->m) syntaxerror("internal error: undefined function");
747     state->initcode = abc_nop(state->initcode);
748     state->initcode = abc_nop(state->initcode);
749     state->initcode = abc_nop(state->initcode);
750     state->m->code = code_append(state->initcode, $11);state->initcode=0;
751     endfunction()
752 }
753
754 /* ------------ variables --------------------------- */
755
756 MAYBEEXPRESSION : '=' EXPRESSION {$$=$2;}
757                 |                {$$.c=abc_pushundefined(0);
758                                   $$.t=TYPE_ANY;
759                                  }
760
761 VAR : "const" | "var"
762 VARIABLE_DECLARATION : VAR T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION {
763     if(variable_exists($2->text))
764         syntaxerror("Variable %s already defined", $2->text);
765    
766     if(!is_subtype_of($4.t, $3)) {
767         syntaxerror("Can't convert %s to %s", $4.t->name, 
768                                               $3->name);
769     }
770
771     int index = new_variable($2->text, $3);
772     
773     if($3) {
774         if($4.c->prev || $4.c->opcode != OPCODE_PUSHUNDEFINED) {
775             $$ = $4.c;
776             $$ = converttype($$, $4.t, $3);
777             $$ = abc_setlocal($$, index);
778         } else {
779             $$ = defaultvalue(0, $3);
780             $$ = abc_setlocal($$, index);
781         }
782
783         /* push default value for type on stack */
784         state->initcode = defaultvalue(state->initcode, $3);
785         state->initcode = abc_setlocal(state->initcode, index);
786     } else {
787         /* only bother to actually set this variable if its syntax is either
788             var x:type;
789            or
790             var x=expr;
791         */
792         if($4.c->prev || $4.c->opcode != OPCODE_PUSHUNDEFINED) {
793             $$ = $4.c;
794             $$ = abc_coerce_a($$);
795             $$ = abc_setlocal($$, index);
796         } else {
797             $$ = code_new();
798         }
799     }
800     
801     /* that's the default for a local register, anyway
802         else {
803         state->initcode = abc_pushundefined(state->initcode);
804         state->initcode = abc_setlocal(state->initcode, index);
805     }*/
806     printf("variable %s -> %d (%s)\n", $2->text, index, $4.t?$4.t->name:"");
807 }
808 ASSIGNMENT :           T_IDENTIFIER '=' EXPRESSION {
809     class_signature_t*type=0;
810     int i = find_variable($1->text, &type);
811     $$ = $3.c;
812     if(!type && $3.t) {
813         // convert to "any" type, the register is untyped
814         $$ = abc_coerce_a($$);
815     } else {
816         // TODO: convert ints to strings etc.
817     }
818     $$ = abc_setlocal($$, i);
819 }
820
821 /* ------------ control flow ------------------------- */
822
823 MAYBEELSE:  %prec prec_none {$$ = code_new();}
824 MAYBEELSE: "else" CODEBLOCK {$$=$2;}
825 //MAYBEELSE: ';' "else" CODEBLOCK {$$=$3;}
826
827 IF  : "if" '(' {new_state();} EXPRESSION ')' CODEBLOCK MAYBEELSE {
828     $$ = state->initcode;state->initcode=0;
829
830     $$ = code_append($$, $4.c);
831     code_t*myjmp,*myif = $$ = abc_iffalse($$, 0);
832    
833     $$ = code_append($$, $6);
834     if($7) {
835         myjmp = $$ = abc_jump($$, 0);
836     }
837     myif->branch = $$ = abc_label($$);
838     if($7) {
839         $$ = code_append($$, $7);
840         myjmp->branch = $$ = abc_label($$);
841     }
842     
843     $$ = killvars($$);old_state();
844 }
845
846 FOR_INIT : {$$=code_new();}
847 FOR_INIT : ASSIGNMENT | VARIABLE_DECLARATION | VOIDEXPRESSION
848
849 FOR : "for" '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRESSION ')' CODEBLOCK {
850     $$ = state->initcode;state->initcode=0;
851
852     $$ = code_append($$, $4);
853     code_t*loopstart = $$ = abc_label($$);
854     $$ = code_append($$, $6.c);
855     code_t*myif = $$ = abc_iffalse($$, 0);
856     $$ = code_append($$, $10);
857     $$ = code_append($$, $8);
858     $$ = abc_jump($$, loopstart);
859     code_t*out = $$ = abc_label($$);
860     breakjumpsto($$, out);
861     myif->branch = out;
862
863     $$ = killvars($$);old_state();
864 }
865
866 WHILE : "while" '(' {new_state();} EXPRESSION ')' CODEBLOCK {
867     $$ = state->initcode;state->initcode=0;
868
869     code_t*myjmp = $$ = abc_jump($$, 0);
870     code_t*loopstart = $$ = abc_label($$);
871     $$ = code_append($$, $6);
872     myjmp->branch = $$ = abc_label($$);
873     $$ = code_append($$, $4.c);
874     $$ = abc_iftrue($$, loopstart);
875     code_t*out = $$ = abc_label($$);
876     breakjumpsto($$, out);
877
878     $$ = killvars($$);old_state();
879 }
880
881 BREAK : "break" {
882     $$ = abc___break__(0);
883 }
884
885 /* ------------ packages and imports ---------------- */
886
887 PACKAGE_DECLARATION : "package" MULTILEVELIDENTIFIER '{' {startpackage($2)} MAYBECODE '}' {endpackage()}
888 PACKAGE_DECLARATION : "package" '{' {startpackage(0)} MAYBECODE '}' {endpackage()}
889
890 PACKAGE: PACKAGE '.' X_IDENTIFIER {$$ = concat3($1,$2,$3);}
891 PACKAGE: X_IDENTIFIER             {$$=$1;}
892
893 IMPORT : "import" PACKAGE '.' X_IDENTIFIER {
894        class_signature_t*c = registry_findclass($2->text, $4->text);
895        if(!c) 
896             syntaxerror("Couldn't import %s.%s\n", $2->text, $4->text);
897        state_has_imports();
898        dict_put(state->imports, $4->text, c);
899        $$=0;
900 }
901 IMPORT : "import" PACKAGE '.' '*' {
902        NEW(import_t,i);
903        i->package = $2->text;
904        state_has_imports();
905        list_append(state->wildcard_imports, i);
906        $$=0;
907 }
908
909 /* ------------ classes and interfaces -------------- */
910
911 MODIFIERS : {$$=empty_token();}
912 MODIFIERS : MODIFIER_LIST {$$=$1}
913 MODIFIER_LIST : MODIFIER MODIFIER_LIST {extend($2,$1);$$=$2;}
914 MODIFIER_LIST : MODIFIER               {$$=empty_token();extend($$,$1);}
915 MODIFIER : KW_PUBLIC | KW_PRIVATE | KW_PROTECTED | KW_STATIC | KW_DYNAMIC | KW_FINAL | KW_OVERRIDE | KW_NATIVE | KW_INTERNAL
916
917 EXTENDS : {$$=registry_getobjectclass();}
918 EXTENDS : KW_EXTENDS PACKAGEANDCLASS {$$=$2;}
919
920 EXTENDS_LIST : {$$=list_new();}
921 EXTENDS_LIST : KW_EXTENDS PACKAGEANDCLASS_LIST {$$=$2;}
922
923 IMPLEMENTS_LIST : {$$=list_new();}
924 IMPLEMENTS_LIST : KW_IMPLEMENTS PACKAGEANDCLASS_LIST {$$=$2;}
925
926 CLASS_DECLARATION : MODIFIERS "class" T_IDENTIFIER 
927                               EXTENDS IMPLEMENTS_LIST 
928                               '{' {startclass($1,$3,$4,$5, 0);} 
929                               MAYBE_DECLARATION_LIST 
930                               '}' {endclass();}
931 INTERFACE_DECLARATION : MODIFIERS "interface" T_IDENTIFIER 
932                               EXTENDS_LIST 
933                               '{' {startclass($1,$3,0,$4,1);}
934                               MAYBE_IDECLARATION_LIST 
935                               '}' {endclass();}
936
937 /* ------------- package + class ids --------------- */
938
939 PACKAGEANDCLASS : T_IDENTIFIER {
940
941     /* try current package */
942     $$ = registry_findclass(state->package, $1->text);
943
944     /* try explicit imports */
945     dictentry_t* e = dict_get_slot(state->imports, $1->text);
946     while(e) {
947         if($$)
948             break;
949         if(!strcmp(e->key, $1->text)) {
950             $$ = (class_signature_t*)e->data;
951         }
952         e = e->next;
953     }
954
955     /* try package.* imports */
956     import_list_t*l = state->wildcard_imports;
957     while(l) {
958         if($$)
959             break;
960         //printf("does package %s contain a class %s?\n", l->import->package, $1->text);
961         $$ = registry_findclass(l->import->package, $1->text);
962         l = l->next;
963     }
964
965     /* try global package */
966     if(!$$) {
967         $$ = registry_findclass("", $1->text);
968     }
969
970     if(!$$) syntaxerror("Could not find class %s\n", $1->text);
971 }
972 PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {
973     $$ = registry_findclass($1->text, $3->text);
974     if(!$$) syntaxerror("Couldn't find class %s.%s\n", $1->text, $3->text);
975 }
976
977
978 /* ----------function calls, constructor calls ------ */
979
980 MAYBE_PARAM_VALUES :  %prec prec_none {$$=0;}
981 MAYBE_PARAM_VALUES : '(' MAYBE_EXPRESSION_LIST ')' {$$=$2}
982
983 MAYBE_EXPRESSION_LIST : {$$=0;}
984 MAYBE_EXPRESSION_LIST : EXPRESSION_LIST
985 EXPRESSION_LIST : EXPRESSION                     {$$=list_new();
986                                                   typedcode_t*t = malloc(sizeof(typedcode_t));
987                                                   *t = $1;
988                                                   list_append($$, t);}
989 EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {$$=$1;
990                                                   typedcode_t*t = malloc(sizeof(typedcode_t));
991                                                   *t = $3;
992                                                   list_append($$, t);}
993
994 NEW : "new" PACKAGEANDCLASS MAYBE_PARAM_VALUES {
995     MULTINAME(m, $2);
996     $$.c = code_new();
997     $$.c = abc_findpropstrict2($$.c, &m);
998     typedcode_list_t*l = $3;
999     int len = 0;
1000     while(l) {
1001         $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
1002         l = l->next;
1003         len ++;
1004     }
1005     $$.c = abc_constructprop2($$.c, &m, len);
1006     $$.t = $2;
1007 }
1008
1009 FUNCTIONCALL : T_IDENTIFIER '(' MAYBE_EXPRESSION_LIST ')' {
1010     /* TODO: use abc_call (for calling local variables),
1011              abc_callstatic (for calling own methods) */
1012     $$.c = code_new();
1013     $$.c = abc_findpropstrict($$.c, $1->text);
1014     typedcode_list_t*l = $3;
1015     int len = 0;
1016     while(l) {
1017         $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
1018         l = l->next;
1019         len ++;
1020     }
1021     $$.c = abc_callproperty($$.c, $1->text, len);
1022     /* TODO: look up the functions's return value */
1023     $$.t = TYPE_ANY;
1024 }
1025
1026 RETURN: "return" %prec prec_none {
1027     $$ = abc_returnvoid(0);
1028 }
1029 RETURN: "return" EXPRESSION {
1030     $$ = $2.c;
1031     $$ = abc_returnvalue($$);
1032 }
1033
1034 TYPE : PACKAGEANDCLASS {$$=$1;}
1035      | '*'        {$$=registry_getanytype();}
1036      |  "String"  {$$=registry_getstringclass();}
1037      |  "int"     {$$=registry_getintclass();}
1038      |  "uint"    {$$=registry_getuintclass();}
1039      |  "Boolean" {$$=registry_getbooleanclass();}
1040      |  "Number"  {$$=registry_getnumberclass();}
1041
1042 MAYBETYPE: ':' TYPE {$$=$2;}
1043 MAYBETYPE:          {$$=0;}
1044
1045 //FUNCTION_HEADER:      NAMESPACE MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')' 
1046 FUNCTION_HEADER:      MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
1047                       MAYBETYPE
1048
1049 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER
1050 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_IDENTIFIER
1051 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_STRING
1052
1053 //NAMESPACE :              {$$=empty_token();}
1054 //NAMESPACE : T_IDENTIFIER {$$=$1};
1055
1056 CONSTANT : T_BYTE {$$.c = abc_pushbyte(0, $1);
1057                    //MULTINAME(m, registry_getintclass());
1058                    //$$.c = abc_coerce2($$.c, &m); // FIXME
1059                    $$.t = TYPE_INT;
1060                   }
1061 CONSTANT : T_SHORT {$$.c = abc_pushshort(0, $1);
1062                     $$.t = TYPE_INT;
1063                    }
1064 CONSTANT : T_INT {$$.c = abc_pushint(0, $1);
1065                   $$.t = TYPE_INT;
1066                  }
1067 CONSTANT : T_UINT {$$.c = abc_pushuint(0, $1);
1068                    $$.t = TYPE_UINT;
1069                   }
1070 CONSTANT : T_FLOAT {$$.c = abc_pushdouble(0, $1);
1071                     $$.t = TYPE_FLOAT;
1072                    }
1073 CONSTANT : T_STRING {$$.c = abc_pushstring(0, $1);
1074                      $$.t = TYPE_STRING;
1075                     }
1076 CONSTANT : KW_TRUE {$$.c = abc_pushtrue(0);
1077                     $$.t = TYPE_BOOLEAN;
1078                    }
1079 CONSTANT : KW_FALSE {$$.c = abc_pushfalse(0);
1080                      $$.t = TYPE_BOOLEAN;
1081                     }
1082 CONSTANT : KW_NULL {$$.c = abc_pushnull(0);
1083                     $$.t = TYPE_NULL;
1084                    }
1085
1086 USE_NAMESPACE : "use" "namespace" T_IDENTIFIER
1087
1088
1089 EXPRESSION : E %prec prec_none  /*precedence below '-x'*/ {$$ = $1;}
1090 VOIDEXPRESSION : E %prec prec_none {$$=$1.c;/*calculate and discard*/$$=abc_pop($$);}
1091
1092 E : CONSTANT
1093 E : VAR_READ %prec T_IDENTIFIER {$$ = $1;}
1094 E : NEW                         {$$ = $1;}
1095 E : T_REGEXP                    {$$.c = abc_pushundefined(0); /* FIXME */
1096                                  $$.t = TYPE_ANY;
1097                                 }
1098 E : FUNCTIONCALL
1099 E : E '<' E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterequals($$.c);$$.c=abc_not($$.c);
1100              $$.t = TYPE_BOOLEAN;
1101             }
1102 E : E '>' E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterthan($$.c);
1103              $$.t = TYPE_BOOLEAN;
1104             }
1105 E : E "<=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterthan($$.c);$$.c=abc_not($$.c);
1106               $$.t = TYPE_BOOLEAN;
1107              }
1108 E : E ">=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterequals($$.c);
1109               $$.t = TYPE_BOOLEAN;
1110              }
1111 E : E "==" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c);
1112               $$.t = TYPE_BOOLEAN;
1113              }
1114 E : E "===" E {$$.c = code_append($1.c,$3.c);$$.c = abc_strictequals($$.c);
1115               $$.t = TYPE_BOOLEAN;
1116              }
1117 E : E "!=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c);$$.c = abc_not($$.c);
1118               $$.t = TYPE_BOOLEAN;
1119              }
1120
1121 E : E "||" E {$$.t = join_types($1.t, $3.t, 'O');
1122               $$.c = $1.c;
1123               $$.c = converttype($$.c, $1.t, $$.t);
1124               $$.c = abc_dup($$.c);
1125               code_t*jmp = $$.c = abc_iftrue($$.c, 0);
1126               $$.c = abc_pop($$.c);
1127               $$.c = code_append($$.c,$3.c);
1128               $$.c = converttype($$.c, $1.t, $$.t);
1129               code_t*label = $$.c = abc_label($$.c);
1130               jmp->branch = label;
1131              }
1132 E : E "&&" E {$$.t = join_types($1.t, $3.t, 'A');
1133               $$.c = $1.c;
1134               $$.c = converttype($$.c, $1.t, $$.t);
1135               $$.c = abc_dup($$.c);
1136               code_t*jmp = $$.c = abc_iffalse($$.c, 0);
1137               $$.c = abc_pop($$.c);
1138               $$.c = code_append($$.c,$3.c);
1139               $$.c = converttype($$.c, $1.t, $$.t);
1140               code_t*label = $$.c = abc_label($$.c);
1141               jmp->branch = label;              
1142              }
1143
1144 E : '!' E    {$$.c=$2.c;
1145               $$.c = abc_not($$.c);
1146               $$.t = TYPE_BOOLEAN;
1147              }
1148
1149 E : E '-' E
1150 E : E '/' E
1151 E : E '+' E {$$.c = code_append($1.c,$3.c);$$.c = abc_add($$.c);$$.c=abc_coerce_a($$.c);
1152              $$.t = join_types($1.t, $3.t, '+');
1153             }
1154 E : E '%' E {$$.c = code_append($1.c,$3.c);$$.c = abc_modulo($$.c);$$.c=abc_coerce_a($$.c);
1155              $$.t = join_types($1.t, $3.t, '%');
1156             }
1157 E : E '*' E {$$.c = code_append($1.c,$3.c);$$.c = abc_multiply($$.c);$$.c=abc_coerce_a($$.c);
1158              $$.t = join_types($1.t, $3.t, '*');
1159             }
1160
1161 E : E "as" TYPE
1162 E : E "is" TYPE
1163 E : '(' E ')' {$$=$2;}
1164 E : '-' E {$$=$2;}
1165
1166 E : LH "+=" E {$$.c = $1.read;$$.c=code_append($$.c,$3.c);$$.c=abc_add($$.c);
1167                class_signature_t*type = join_types($1.type, $3.t, '+');
1168                $$.c=converttype($$.c, type, $1.type);
1169                $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1170                $$.t = $1.type;
1171               }
1172 E : LH "-=" E {$$.c = $1.read;$$.c=code_append($$.c,$3.c);$$.c=abc_add($$.c);
1173                class_signature_t*type = join_types($1.type, $3.t, '-');
1174                $$.c=converttype($$.c, type, $1.type);
1175                $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1176                $$.t = $1.type;
1177               }
1178
1179 // TODO: use inclocal where appropriate
1180 E : LH "++" {$$.c = $1.read;
1181              class_signature_t*type = $1.type;
1182              if(TYPE_IS_INT(type) || TYPE_IS_UINT(type)) {
1183                  $$.c=abc_increment_i($$.c);
1184              } else {
1185                  $$.c=abc_increment($$.c);
1186                  type = TYPE_NUMBER;
1187              }
1188              $$.c=converttype($$.c, type, $1.type);
1189              $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1190              $$.t = $1.type;
1191             }
1192 E : LH "--" {$$.c = $1.read;
1193              class_signature_t*type = $1.type;
1194              if(TYPE_IS_INT(type) || TYPE_IS_UINT(type)) {
1195                  $$.c=abc_decrement_i($$.c);
1196              } else {
1197                  $$.c=abc_decrement($$.c);
1198                  type = TYPE_NUMBER;
1199              }
1200              $$.c=converttype($$.c, type, $1.type);
1201              $$.c=abc_dup($$.c);$$.c=code_append($$.c,$1.write);
1202              $$.t = $1.type;
1203             }
1204
1205 LH: T_IDENTIFIER {
1206   int i = find_variable($1->text, &$$.type);
1207   $$.read = abc_getlocal(0, i);
1208   $$.write = abc_setlocal(0, i);
1209 }
1210
1211
1212 VAR_READ : T_IDENTIFIER {
1213     int i = find_variable($1->text, &$$.t);
1214     $$.c = abc_getlocal(0, i);
1215 }
1216
1217 //VARIABLE : T_IDENTIFIER
1218 //VARIABLE : VARIABLE '.' T_IDENTIFIER
1219 //VARIABLE : VARIABLE ".." T_IDENTIFIER // descendants
1220 //VARIABLE : VARIABLE "::" VARIABLE // namespace declaration
1221 //VARIABLE : VARIABLE "::" '[' EXPRESSION ']' // qualified expression
1222 //VARIABLE : VARIABLE '[' EXPRESSION ']' // unqualified expression
1223
1224 // keywords which also may be identifiers
1225 X_IDENTIFIER : T_IDENTIFIER | KW_PACKAGE
1226
1227 GETSET : "get" {$$=$1;}
1228        | "set" {$$=$1;}
1229        |       {$$=empty_token();}
1230
1231 MAYBE_PARAM_LIST: {$$=list_new();}
1232 MAYBE_PARAM_LIST: PARAM_LIST {$$=$1;}
1233 PARAM_LIST: PARAM_LIST ',' PARAM {$$ =$1;         list_append($$, $3);}
1234 PARAM_LIST: PARAM                {$$ = list_new();list_append($$, $1);}
1235 PARAM:  T_IDENTIFIER ':' TYPE {$$ = malloc(sizeof(param_t));
1236                                $$->name=$1->text;$$->type = $3;}
1237 PARAM:  T_IDENTIFIER          {$$ = malloc(sizeof(param_t));
1238                                $$->name=$1->text;$$->type = TYPE_ANY;}
1239
1240 DECLARATION : VARIABLE_DECLARATION
1241 DECLARATION : FUNCTION_DECLARATION
1242
1243 IDECLARATION : VARIABLE_DECLARATION
1244 IDECLARATION : FUNCTION_DECLARATION
1245
1246 //IDENTIFIER_LIST : T_IDENTIFIER ',' IDENTIFIER_LIST {extend($3,$1);$$=$3;}
1247 //IDENTIFIER_LIST : T_IDENTIFIER                     {$$=empty_token();extend($$,$1);}
1248
1249 MULTILEVELIDENTIFIER : MULTILEVELIDENTIFIER '.' X_IDENTIFIER {$$=$1;extend_s($$, ".", $3)}
1250 MULTILEVELIDENTIFIER : T_IDENTIFIER                 {$$=$1;extend($$,$1)};
1251
1252 PACKAGEANDCLASS_LIST : PACKAGEANDCLASS {$$=list_new();list_append($$, $1);}
1253 PACKAGEANDCLASS_LIST : PACKAGEANDCLASS_LIST ',' PACKAGEANDCLASS {$$=$1;list_append($$,$3);}
1254
1255 MAYBE_DECLARATION_LIST : 
1256 MAYBE_DECLARATION_LIST : DECLARATION_LIST
1257 DECLARATION_LIST : DECLARATION
1258 DECLARATION_LIST : DECLARATION_LIST DECLARATION
1259
1260 MAYBE_IDECLARATION_LIST : 
1261 MAYBE_IDECLARATION_LIST : IDECLARATION_LIST
1262 IDECLARATION_LIST : IDECLARATION
1263 IDECLARATION_LIST : IDECLARATION_LIST FUNCTION_HEADER
1264
1265 // chapter 14
1266 // 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
1267 // syntactic keywords: each get set namespace include dynamic final native override static
1268