Appearance
| 1 | namespace Syntax.Parsers.Definitions is | |
| 2 | use Collections.MutableMap; | |
| 3 | use Collections.MAP; | |
| 4 | ||
| 5 | use Syntax.Parsers.Expressions.PRECEDENCE; | |
| 6 | ||
| 7 | use Source; | |
| 8 | ||
| 9 | use Logging; | |
| 10 | ||
| 11 | enum PrecedenceRestoreStatus is | |
| 12 | NO_RESTORE_NEEDED, | |
| 13 | REMOVE_PRECEDENCE, | |
| 14 | RESTORE_PRECEDENCE | |
| 15 | si | |
| 16 | ||
| 17 | class PRAGMA( | |
| 18 | pragma_parser: Parser[Trees.Pragmas.PRAGMA], | |
| 19 | definition_parser: Parser[Trees.Definitions.Definition], | |
| 20 | precedence_map: MutableMap[string,PRECEDENCE] | |
| 21 | ): Base[Trees.Definitions.PRAGMA] is | |
| 22 | // FIXME: use enum parse | |
| 23 | _precedence_names: MutableMap[string,PRECEDENCE]; | |
| 24 | ||
| 25 | super(); | |
| 26 | ||
| 27 | init(..) is | |
| 28 | _precedence_names = MAP[string,PRECEDENCE](); | |
| 29 | ||
| 30 | _precedence_names.add("user-1", PRECEDENCE.USER_1); | |
| 31 | _precedence_names.add("boolean", PRECEDENCE.BOOLEAN); | |
| 32 | _precedence_names.add("user-2", PRECEDENCE.USER_2); | |
| 33 | _precedence_names.add("relational", PRECEDENCE.RELATIONAL); | |
| 34 | _precedence_names.add("user-3", PRECEDENCE.USER_3); | |
| 35 | _precedence_names.add("range", PRECEDENCE.RANGE); | |
| 36 | _precedence_names.add("user-4", PRECEDENCE.USER_4); | |
| 37 | _precedence_names.add("shift", PRECEDENCE.SHIFT); | |
| 38 | _precedence_names.add("user-5", PRECEDENCE.USER_5); | |
| 39 | _precedence_names.add("bitwise", PRECEDENCE.BITWISE); | |
| 40 | _precedence_names.add("user-6", PRECEDENCE.USER_6); | |
| 41 | _precedence_names.add("addition", PRECEDENCE.ADDITION); | |
| 42 | _precedence_names.add("user-7", PRECEDENCE.USER_7); | |
| 43 | _precedence_names.add("multiplication", PRECEDENCE.MULTIPLICATION); | |
| 44 | _precedence_names.add("user-8", PRECEDENCE.USER_8); | |
| 45 | _precedence_names.add("member", PRECEDENCE.MEMBER); | |
| 46 | _precedence_names.add("primary", PRECEDENCE.PRIMARY); | |
| 47 | si | |
| 48 | ||
| 49 | parse(context: CONTEXT) -> Trees.Definitions.PRAGMA? is | |
| 50 | let pragma = pragma_parser.parse(context); | |
| 51 | ||
| 52 | // FIXME: factor this out | |
| 53 | if pragma? /\ !pragma.is_poisoned then | |
| 54 | let operator_name: string? mut = null; | |
| 55 | let precedence_to_restore: PRECEDENCE mut = _; | |
| 56 | ||
| 57 | let restore_status mut = PrecedenceRestoreStatus.NO_RESTORE_NEEDED; | |
| 58 | ||
| 59 | if | |
| 60 | pragma.is_name_equal_to("precedence") | |
| 61 | then | |
| 62 | let is_precedence_valid mut = true; | |
| 63 | ||
| 64 | operator_name = pragma.try_get_string_literal_at(0); | |
| 65 | let precedence_name = pragma.try_get_string_literal_at(1); | |
| 66 | ||
| 67 | if !operator_name? then | |
| 68 | context.error(pragma.location, "expected operator name argument"); | |
| 69 | ||
| 70 | is_precedence_valid = false; | |
| 71 | fi | |
| 72 | ||
| 73 | let precedence_to_set: PRECEDENCE mut = _; | |
| 74 | ||
| 75 | if !precedence_name? then | |
| 76 | context.error(pragma.location, "expected operator precedence argument"); | |
| 77 | ||
| 78 | is_precedence_valid = false; | |
| 79 | elif !_precedence_names.try_get_value(precedence_name, precedence_to_set ref) then | |
| 80 | context.error(pragma.location, "unknown precedence name {precedence_name}"); | |
| 81 | ||
| 82 | is_precedence_valid = false; | |
| 83 | fi | |
| 84 | ||
| 85 | if is_precedence_valid then | |
| 86 | if | |
| 87 | cast int(precedence_to_set) < cast int(PRECEDENCE.USER_1) \/ | |
| 88 | cast int(precedence_to_set) > cast int(PRECEDENCE.USER_8) | |
| 89 | then | |
| 90 | context.error(pragma.location, "precedence must be between user-1 and user-8"); | |
| 91 | is_precedence_valid = false; | |
| 92 | fi | |
| 93 | fi | |
| 94 | ||
| 95 | if is_precedence_valid /\ operator_name? then | |
| 96 | if precedence_map.try_get_value(operator_name, precedence_to_restore ref) then | |
| 97 | restore_status = PrecedenceRestoreStatus.RESTORE_PRECEDENCE; | |
| 98 | else | |
| 99 | restore_status = PrecedenceRestoreStatus.REMOVE_PRECEDENCE; | |
| 100 | fi | |
| 101 | ||
| 102 | precedence_map[operator_name] = precedence_to_set; | |
| 103 | fi | |
| 104 | fi | |
| 105 | ||
| 106 | let definition = definition_parser.parse(context); | |
| 107 | ||
| 108 | if operator_name? then | |
| 109 | if restore_status == PrecedenceRestoreStatus.RESTORE_PRECEDENCE then | |
| 110 | precedence_map[operator_name] = precedence_to_restore; | |
| 111 | elif restore_status == PrecedenceRestoreStatus.REMOVE_PRECEDENCE then | |
| 112 | precedence_map.remove(operator_name); | |
| 113 | fi | |
| 114 | fi | |
| 115 | ||
| 116 | if definition? /\ !definition.is_poisoned then | |
| 117 | return Trees.Definitions.PRAGMA(pragma.location::definition.location, pragma, definition); | |
| 118 | fi | |
| 119 | fi | |
| 120 | ||
| 121 | return null; | |
| 122 | si | |
| 123 | si | |
| 124 | si |