Appearance
| 1 | namespace Syntax.Parsers.Definitions is | |
| 2 | ||
| 3 | use Source; | |
| 4 | ||
| 5 | class ENUM( | |
| 6 | identifier_parser: Parser[Trees.Identifiers.Identifier], | |
| 7 | modifier_list_parser: Parser[Trees.Modifiers.LIST], | |
| 8 | expression_parser: Parser[Trees.Expressions.Expression] | |
| 9 | ): Base[Trees.Definitions.ENUM] is | |
| 10 | super(); | |
| 11 | ||
| 12 | parse(context: CONTEXT) -> Trees.Definitions.ENUM? is | |
| 13 | context.next_token(Lexical.TOKEN.ENUM); | |
| 14 | let start = context.location; | |
| 15 | let name = identifier_parser.parse(context); | |
| 16 | ||
| 17 | let modifiers = modifier_list_parser.parse(context)!; | |
| 18 | ||
| 19 | let members = Collections.LIST[Trees.Definitions.ENUM_MEMBER](); | |
| 20 | ||
| 21 | let expect_si mut = false; | |
| 22 | ||
| 23 | if (name? /\ !name.is_poisoned) \/ context.current.token == Lexical.TOKEN.IS then | |
| 24 | if context.next_token(Lexical.TOKEN.IS) then | |
| 25 | expect_si = true; | |
| 26 | ||
| 27 | while context.current.token != Lexical.TOKEN.SI do | |
| 28 | if members.count > 0 then | |
| 29 | if !context.next_token(Lexical.TOKEN.COMMA) then | |
| 30 | expect_si = false; | |
| 31 | break; | |
| 32 | fi | |
| 33 | ||
| 34 | // Trailing comma: stop when the comma is | |
| 35 | // followed by the closing `si` rather than | |
| 36 | // another member. | |
| 37 | if context.current.token == Lexical.TOKEN.SI then | |
| 38 | break; | |
| 39 | fi | |
| 40 | fi | |
| 41 | ||
| 42 | let member_name = identifier_parser.parse(context); | |
| 43 | ||
| 44 | if member_name? then | |
| 45 | let member_end mut = member_name.location; | |
| 46 | let member_initializer: Trees.Expressions.Expression? mut = null; | |
| 47 | if context.current.token == Lexical.TOKEN.ASSIGN then | |
| 48 | context.next_token(); | |
| 49 | ||
| 50 | member_initializer = expression_parser.parse(context)!; | |
| 51 | ||
| 52 | if member_initializer.is_poisoned then | |
| 53 | expect_si = false; | |
| 54 | fi | |
| 55 | ||
| 56 | member_end = member_initializer.location; | |
| 57 | fi | |
| 58 | ||
| 59 | members.add(Trees.Definitions.ENUM_MEMBER(member_name.location::member_end, member_name, member_initializer)); | |
| 60 | else | |
| 61 | expect_si = false; | |
| 62 | break; | |
| 63 | fi | |
| 64 | od | |
| 65 | fi | |
| 66 | fi | |
| 67 | ||
| 68 | let end = context.location; | |
| 69 | ||
| 70 | if | |
| 71 | expect_si | |
| 72 | then | |
| 73 | context.next_token(Lexical.TOKEN.SI); | |
| 74 | fi | |
| 75 | ||
| 76 | if name? then | |
| 77 | return Trees.Definitions.ENUM(start::end, name, modifiers, members); | |
| 78 | fi | |
| 79 | ||
| 80 | return null; | |
| 81 | si | |
| 82 | si | |
| 83 | si |