Appearance
| 1 | namespace Syntax.Process is | |
| 2 | use Collections | |
| 3 | ||
| 4 | use Type = Semantic.Types.Type | |
| 5 | use Value = IR.Values.Value | |
| 6 | use Variable = Semantic.Symbols.Variable | |
| 7 | ||
| 8 | // Per-build state the compile-expressions pass family records on | |
| 9 | // statement nodes, read downstream by IL generation. Each struct is | |
| 10 | // hosted as a field on its statement class and knows how to clear | |
| 11 | // itself; the statement classes carry read-only forwarders and no | |
| 12 | // knowledge of the contents. See NodeStateStore for the companion | |
| 13 | // store-based pattern for sparse state. | |
| 14 | struct STATEMENT_STATE is | |
| 15 | value: Value? public | |
| 16 | want_value: bool public | |
| 17 | // Set alongside want_value where a value is wanted but a void | |
| 18 | // one is acceptable: the body of a function literal whose | |
| 19 | // return type is still being inferred. An `if` / `case` there | |
| 20 | // whose arms only yield void produces no value at all and | |
| 21 | // settles the return as void, rather than being reported for | |
| 22 | // having no value to give. | |
| 23 | void_tolerated: bool public | |
| 24 | // Set by the statement-list visitor's function-tail judge when a | |
| 25 | // demanded tail delivered a non-void value (well- or ill-typed): | |
| 26 | // the implicit return consumed the body's return obligation. A | |
| 27 | // tail that turned out void leaves it false, and the body falls | |
| 28 | // through to the default-value return under the definite-return | |
| 29 | // warning. | |
| 30 | function_tail_delivered: bool public | |
| 31 | ||
| 32 | init() is | |
| 33 | si | |
| 34 | ||
| 35 | clear() is | |
| 36 | value = null | |
| 37 | want_value = false | |
| 38 | void_tolerated = false | |
| 39 | function_tail_delivered = false | |
| 40 | si | |
| 41 | ||
| 42 | clear_outputs() is | |
| 43 | value = null | |
| 44 | function_tail_delivered = false | |
| 45 | si | |
| 46 | si | |
| 47 | ||
| 48 | struct LIST_DISPOSAL_STATE is | |
| 49 | variables_to_dispose: Collections.LIST[Variable]? public | |
| 50 | want_dispose: bool public | |
| 51 | ||
| 52 | init() is | |
| 53 | si | |
| 54 | ||
| 55 | add(v: Variable) is | |
| 56 | want_dispose = true | |
| 57 | ||
| 58 | let list = variables_to_dispose ?? Collections.LIST[Variable]() | |
| 59 | variables_to_dispose = list | |
| 60 | ||
| 61 | list.add(v) | |
| 62 | si | |
| 63 | ||
| 64 | clear() is | |
| 65 | variables_to_dispose = null | |
| 66 | want_dispose = false | |
| 67 | si | |
| 68 | si | |
| 69 | ||
| 70 | struct EXPECTED_TYPE_STATE is | |
| 71 | expected_type: Type? public | |
| 72 | expected_type_error_message: string? public | |
| 73 | ||
| 74 | init() is | |
| 75 | si | |
| 76 | ||
| 77 | set(expected_type: Type?, error_message: string?) is | |
| 78 | self.expected_type = expected_type | |
| 79 | self.expected_type_error_message = error_message | |
| 80 | si | |
| 81 | ||
| 82 | clear() is | |
| 83 | expected_type = null | |
| 84 | expected_type_error_message = null | |
| 85 | si | |
| 86 | si | |
| 87 | ||
| 88 | struct CASE_STATE is | |
| 89 | expected_type: Type? public | |
| 90 | expected_type_error_message: string? public | |
| 91 | is_exhaustive: bool public | |
| 92 | requires_default_fallthrough: bool public | |
| 93 | // The scrutinee evaluated once into a temp, shared across every | |
| 94 | // `when` label test and pattern arm. `scrutinee_spill` is | |
| 95 | // emitted at the start of the case; `scrutinee_load` reads the | |
| 96 | // temp. Built in compile-expressions so every label's | |
| 97 | // value-equality test - also built there - references the one | |
| 98 | // evaluation, matching the single-evaluation semantics the | |
| 99 | // case scrutinee has always had. | |
| 100 | scrutinee_spill: Value? public | |
| 101 | scrutinee_load: Value? public | |
| 102 | ||
| 103 | init() is | |
| 104 | si | |
| 105 | ||
| 106 | set_expected_type(expected_type: Type?, error_message: string?) is | |
| 107 | self.expected_type = expected_type | |
| 108 | self.expected_type_error_message = error_message | |
| 109 | si | |
| 110 | ||
| 111 | set_scrutinee(scrutinee_spill: Value?, scrutinee_load: Value?) is | |
| 112 | self.scrutinee_spill = scrutinee_spill | |
| 113 | self.scrutinee_load = scrutinee_load | |
| 114 | si | |
| 115 | ||
| 116 | clear() is | |
| 117 | expected_type = null | |
| 118 | expected_type_error_message = null | |
| 119 | is_exhaustive = false | |
| 120 | requires_default_fallthrough = false | |
| 121 | scrutinee_spill = null | |
| 122 | scrutinee_load = null | |
| 123 | si | |
| 124 | si | |
| 125 | ||
| 126 | // Per-arm state for a `case` `when` label list: the value-equality | |
| 127 | // test Value built in compile-expressions for each label, parallel | |
| 128 | // to the arm's label expressions. A null entry means no `=~`/`<>` | |
| 129 | // resolved for that label (or it is a `null` label) - generate-il | |
| 130 | // then falls back to a raw compare, or a presence test for `null`. | |
| 131 | struct CASE_MATCH_STATE is | |
| 132 | tests: Collections.LIST[Value?]? public | |
| 133 | ||
| 134 | init() is | |
| 135 | si | |
| 136 | ||
| 137 | clear() is | |
| 138 | tests = null | |
| 139 | si | |
| 140 | si | |
| 141 | si |