+IMPORT : "import" QNAME {
+ classinfo_t*c = $2;
+ if(!c)
+ syntaxerror("Couldn't import class\n");
+ state_has_imports();
+ dict_put(state->imports, c->name, c);
+ $$=0;
+}
+IMPORT : "import" PACKAGE '.' '*' {
+ NEW(import_t,i);
+ i->package = $2->text;
+ state_has_imports();
+ list_append(state->wildcard_imports, i);
+ $$=0;
+}
+
+/* ------------ classes and interfaces -------------- */
+
+MODIFIERS : {$$=empty_token();}
+MODIFIERS : MODIFIER_LIST {$$=$1}
+MODIFIER_LIST : MODIFIER MODIFIER_LIST {extend($2,$1);$$=$2;}
+MODIFIER_LIST : MODIFIER {$$=empty_token();extend($$,$1);}
+MODIFIER : KW_PUBLIC | KW_PRIVATE | KW_PROTECTED | KW_STATIC | KW_DYNAMIC | KW_FINAL | KW_OVERRIDE | KW_NATIVE | KW_INTERNAL
+
+EXTENDS : {$$=registry_getobjectclass();}
+EXTENDS : KW_EXTENDS QNAME {$$=$2;}
+
+EXTENDS_LIST : {$$=list_new();}
+EXTENDS_LIST : KW_EXTENDS QNAME_LIST {$$=$2;}
+
+IMPLEMENTS_LIST : {$$=list_new();}
+IMPLEMENTS_LIST : KW_IMPLEMENTS QNAME_LIST {$$=$2;}
+
+CLASS_DECLARATION : MODIFIERS "class" T_IDENTIFIER
+ EXTENDS IMPLEMENTS_LIST
+ '{' {startclass($1,$3,$4,$5, 0);}
+ MAYBE_DECLARATION_LIST
+ '}' {endclass();}
+INTERFACE_DECLARATION : MODIFIERS "interface" T_IDENTIFIER
+ EXTENDS_LIST
+ '{' {startclass($1,$3,0,$4,1);}
+ MAYBE_IDECLARATION_LIST
+ '}' {endclass();}
+
+/* ------------- package + class ids --------------- */
+
+CLASS: T_IDENTIFIER {
+
+ /* try current package */
+ $$ = registry_findclass(state->package, $1->text);
+
+ /* try explicit imports */
+ dictentry_t* e = dict_get_slot(state->imports, $1->text);
+ while(e) {
+ if($$)
+ break;
+ if(!strcmp(e->key, $1->text)) {
+ $$ = (classinfo_t*)e->data;
+ }
+ e = e->next;
+ }
+
+ /* try package.* imports */
+ import_list_t*l = state->wildcard_imports;
+ while(l) {
+ if($$)
+ break;
+ //printf("does package %s contain a class %s?\n", l->import->package, $1->text);
+ $$ = registry_findclass(l->import->package, $1->text);
+ l = l->next;
+ }
+
+ /* try global package */
+ if(!$$) {
+ $$ = registry_findclass("", $1->text);
+ }
+
+ if(!$$) syntaxerror("Could not find class %s\n", $1->text);
+}
+
+PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {
+ $$ = registry_findclass($1->text, $3->text);
+ if(!$$) syntaxerror("Couldn't find class %s.%s\n", $1->text, $3->text);
+}
+
+QNAME: PACKAGEANDCLASS
+ | CLASS