164 private static final int XSTMT1 = XSTMT1o | XSTMT; // OK in statement framework (anywhere) |
164 private static final int XSTMT1 = XSTMT1o | XSTMT; // OK in statement framework (anywhere) |
165 private static final int XANY1 = XEXPR1o | XDECL1o | XSTMT1o; // Mask: first in statement, declaration, or expression |
165 private static final int XANY1 = XEXPR1o | XDECL1o | XSTMT1o; // Mask: first in statement, declaration, or expression |
166 private static final int XTERM = 0b100000000; // Can terminate (last before EOF) |
166 private static final int XTERM = 0b100000000; // Can terminate (last before EOF) |
167 private static final int XSTART = 0b1000000000; // Boundary, must be XTERM before |
167 private static final int XSTART = 0b1000000000; // Boundary, must be XTERM before |
168 private static final int XERRO = 0b10000000000; // Is an error |
168 private static final int XERRO = 0b10000000000; // Is an error |
|
169 private static final int XBRACESNEEDED = 0b100000000000; // Expect {ANY} LBRACE |
169 |
170 |
170 /** |
171 /** |
171 * An extension of the compiler's TokenKind which adds our combined/processed |
172 * An extension of the compiler's TokenKind which adds our combined/processed |
172 * kinds. Also associates each TK with a union of acceptable kinds of code |
173 * kinds. Also associates each TK with a union of acceptable kinds of code |
173 * position it can occupy. For example: IDENTIFER is XEXPR1|XDECL1|XTERM, |
174 * position it can occupy. For example: IDENTIFER is XEXPR1|XDECL1|XTERM, |
188 // Special |
189 // Special |
189 EOF(TokenKind.EOF, 0), // |
190 EOF(TokenKind.EOF, 0), // |
190 ERROR(TokenKind.ERROR, XERRO), // |
191 ERROR(TokenKind.ERROR, XERRO), // |
191 IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM), // |
192 IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM), // |
192 UNDERSCORE(TokenKind.UNDERSCORE, XERRO), // _ |
193 UNDERSCORE(TokenKind.UNDERSCORE, XERRO), // _ |
193 CLASS(TokenKind.CLASS, XEXPR|XDECL1), // class decl (MAPPED: DOTCLASS) |
194 CLASS(TokenKind.CLASS, XEXPR|XDECL1|XBRACESNEEDED), // class decl (MAPPED: DOTCLASS) |
194 MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1), // @ |
195 MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1), // @ |
195 IMPORT(TokenKind.IMPORT, XDECL1|XSTART), // import -- consider declaration |
196 IMPORT(TokenKind.IMPORT, XDECL1|XSTART), // import -- consider declaration |
196 SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART), // ; |
197 SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART), // ; |
197 |
198 |
198 // Shouldn't see -- error |
199 // Shouldn't see -- error |
200 CONST(TokenKind.CONST, XERRO), // reserved keyword -- const |
201 CONST(TokenKind.CONST, XERRO), // reserved keyword -- const |
201 GOTO(TokenKind.GOTO, XERRO), // reserved keyword -- goto |
202 GOTO(TokenKind.GOTO, XERRO), // reserved keyword -- goto |
202 CUSTOM(TokenKind.CUSTOM, XERRO), // No uses |
203 CUSTOM(TokenKind.CUSTOM, XERRO), // No uses |
203 |
204 |
204 // Declarations |
205 // Declarations |
205 ENUM(TokenKind.ENUM, XDECL1), // enum |
206 ENUM(TokenKind.ENUM, XDECL1|XBRACESNEEDED), // enum |
206 IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL), // implements |
207 IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL), // implements |
207 INTERFACE(TokenKind.INTERFACE, XDECL1), // interface |
208 INTERFACE(TokenKind.INTERFACE, XDECL1|XBRACESNEEDED), // interface |
208 THROWS(TokenKind.THROWS, XDECL), // throws |
209 THROWS(TokenKind.THROWS, XDECL|XBRACESNEEDED), // throws |
209 |
210 |
210 // Primarive type names |
211 // Primarive type names |
211 BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1), // boolean |
212 BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1), // boolean |
212 BYTE(TokenKind.BYTE, XEXPR1|XDECL1), // byte |
213 BYTE(TokenKind.BYTE, XEXPR1|XDECL1), // byte |
213 CHAR(TokenKind.CHAR, XEXPR1|XDECL1), // char |
214 CHAR(TokenKind.CHAR, XEXPR1|XDECL1), // char |
639 } |
644 } |
640 } |
645 } |
641 |
646 |
642 public Completeness parseDeclaration() { |
647 public Completeness parseDeclaration() { |
643 boolean isImport = token.kind == IMPORT; |
648 boolean isImport = token.kind == IMPORT; |
|
649 boolean isBracesNeeded = false; |
644 while (token.kind.isDeclaration()) { |
650 while (token.kind.isDeclaration()) { |
|
651 isBracesNeeded |= token.kind.isBracesNeeded(); |
645 nextToken(); |
652 nextToken(); |
646 } |
653 } |
647 switch (token.kind) { |
654 switch (token.kind) { |
648 case EQ: |
655 case EQ: |
649 // Check for array initializer |
656 // Check for array initializer |
664 switch (in.prevCT.kind) { |
671 switch (in.prevCT.kind) { |
665 case BRACES: |
672 case BRACES: |
666 case SEMI: |
673 case SEMI: |
667 return Completeness.COMPLETE; |
674 return Completeness.COMPLETE; |
668 case IDENTIFIER: |
675 case IDENTIFIER: |
|
676 return isBracesNeeded |
|
677 ? Completeness.DEFINITELY_INCOMPLETE |
|
678 : Completeness.COMPLETE_WITH_SEMI; |
669 case BRACKETS: |
679 case BRACKETS: |
670 return Completeness.COMPLETE_WITH_SEMI; |
680 return Completeness.COMPLETE_WITH_SEMI; |
671 case DOTSTAR: |
681 case DOTSTAR: |
672 if (isImport) { |
682 if (isImport) { |
673 return Completeness.COMPLETE_WITH_SEMI; |
683 return Completeness.COMPLETE_WITH_SEMI; |