Appearance
| 1 | namespace Semantic.DotNet is | |
| 2 | use IO.Std; | |
| 3 | ||
| 4 | use TYPE = System.Type; | |
| 5 | use Collections.LIST; | |
| 6 | use Collections.List; | |
| 7 | ||
| 8 | use Source.LOCATION; | |
| 9 | ||
| 10 | use Types.Type; | |
| 11 | ||
| 12 | class TYPE_WRAPPER: Types.NAMED is | |
| 13 | _symbol_table: SYMBOL_TABLE; | |
| 14 | _dotnet_type: TYPE; | |
| 15 | ||
| 16 | symbol: Symbols.Symbol is | |
| 17 | // _symbol is lazily materialized on first access | |
| 18 | @suppress("presence-test-non-optional") | |
| 19 | if !_symbol? then | |
| 20 | materialize(); | |
| 21 | fi | |
| 22 | ||
| 23 | return _symbol; | |
| 24 | si | |
| 25 | ||
| 26 | init( | |
| 27 | symbol_table: SYMBOL_TABLE, | |
| 28 | dotnet_type: TYPE | |
| 29 | ) is | |
| 30 | super.init(null); | |
| 31 | _symbol_table = symbol_table; | |
| 32 | _dotnet_type = dotnet_type; | |
| 33 | si | |
| 34 | ||
| 35 | materialize() is | |
| 36 | _symbol = _symbol_table.get_symbol(_dotnet_type)!; | |
| 37 | si | |
| 38 | si | |
| 39 | ||
| 40 | class GENERIC_TYPE_WRAPPER: Types.GENERIC is | |
| 41 | _symbol_table: SYMBOL_TABLE; | |
| 42 | _type_mapper: TYPE_MAPPER; | |
| 43 | _dotnet_type: TYPE; | |
| 44 | ||
| 45 | symbol: Symbols.Symbol is | |
| 46 | // _symbol is lazily materialized on first access | |
| 47 | @suppress("presence-test-non-optional") | |
| 48 | if !_symbol? then | |
| 49 | materialize(); | |
| 50 | fi | |
| 51 | ||
| 52 | return _symbol; | |
| 53 | si | |
| 54 | ||
| 55 | init( | |
| 56 | symbol_table: SYMBOL_TABLE, | |
| 57 | type_mapper: TYPE_MAPPER, | |
| 58 | dotnet_type: TYPE | |
| 59 | ) is | |
| 60 | _symbol_table = symbol_table; | |
| 61 | _type_mapper = type_mapper; | |
| 62 | _dotnet_type = dotnet_type; | |
| 63 | si | |
| 64 | ||
| 65 | materialize() is | |
| 66 | let s = _symbol_table.get_symbol(_dotnet_type.get_generic_type_definition()); | |
| 67 | ||
| 68 | let unspecialized = cast Symbols.Classy?(s)!; | |
| 69 | ||
| 70 | let arguments = LIST(); | |
| 71 | ||
| 72 | for a in _dotnet_type.get_generic_arguments() do | |
| 73 | arguments.add(_type_mapper.get_type(a)); | |
| 74 | od | |
| 75 | ||
| 76 | _symbol = create_symbol(unspecialized, arguments); | |
| 77 | si | |
| 78 | ||
| 79 | create_symbol(unspecialized: Symbols.Classy, arguments: List[Types.Type]) -> Symbols.GENERIC => | |
| 80 | Symbols.GENERIC(Source.LOCATION.internal, unspecialized, arguments); | |
| 81 | si | |
| 82 | ||
| 83 | // A reflected `System.Nullable[T]` — the same value-type optional | |
| 84 | // a ghūl-written `T?` produces (Types.NULLABLE), so it must behave | |
| 85 | // identically: optional, widening from T, and rendered with the | |
| 86 | // `?` sugar. Mirrors FUNCTION_TYPE_WRAPPER / TUPLE_TYPE_WRAPPER, | |
| 87 | // which likewise re-declare their behaviour and delegate to the | |
| 88 | // eager type's statics / constructor. | |
| 89 | class NULLABLE_TYPE_WRAPPER: GENERIC_TYPE_WRAPPER is | |
| 90 | is_optional: bool => true; | |
| 91 | ||
| 92 | optional_inner_type: Type? => arguments[0]; | |
| 93 | ||
| 94 | init( | |
| 95 | symbol_table: SYMBOL_TABLE, | |
| 96 | type_mapper: TYPE_MAPPER, | |
| 97 | dotnet_type: TYPE | |
| 98 | ) is | |
| 99 | super.init(symbol_table, type_mapper, dotnet_type); | |
| 100 | si | |
| 101 | ||
| 102 | compare(other: Type) -> Types.MATCH => | |
| 103 | Types.NULLABLE.compare_optional(self, other, super.compare(other)); | |
| 104 | ||
| 105 | create( | |
| 106 | location: LOCATION, | |
| 107 | symbol: Symbols.Classy, | |
| 108 | arguments: Collections.List[Type] | |
| 109 | ) -> Types.GENERIC => | |
| 110 | Types.NULLABLE(location, symbol, arguments); | |
| 111 | ||
| 112 | short_description: string => Types.NULLABLE.get_short_description(self); | |
| 113 | ||
| 114 | to_string() -> string => "{arguments[0]}?"; | |
| 115 | si | |
| 116 | ||
| 117 | // A reflected `Ghul.MAYBE[T]` — the runtime's unconstrained-T | |
| 118 | // optional carrier. The Type-system flag is_maybe drives the | |
| 119 | // implicit conversion to `T?` at slot boundaries; surfacing it as | |
| 120 | // a wrapper subclass means recognition is `isa MAYBE_TYPE_WRAPPER` | |
| 121 | // (no per-call symbol lookup, no behaviour on source-side MAYBE | |
| 122 | // structs being newly compiled inside `ghul-runtime` itself). | |
| 123 | class MAYBE_TYPE_WRAPPER: GENERIC_TYPE_WRAPPER is | |
| 124 | is_maybe: bool => true; | |
| 125 | ||
| 126 | is_optional: bool => true; | |
| 127 | ||
| 128 | optional_inner_type: Type? => arguments[0]; | |
| 129 | ||
| 130 | init( | |
| 131 | symbol_table: SYMBOL_TABLE, | |
| 132 | type_mapper: TYPE_MAPPER, | |
| 133 | dotnet_type: TYPE | |
| 134 | ) is | |
| 135 | super.init(symbol_table, type_mapper, dotnet_type); | |
| 136 | si | |
| 137 | ||
| 138 | // Specialisation (`MAYBE[T]` → `MAYBE[CAT]`) hands off to the | |
| 139 | // eager subclass so the is_maybe flag survives every rewrite — | |
| 140 | // mirrors NULLABLE_TYPE_WRAPPER's hand-off to Types.NULLABLE. | |
| 141 | create( | |
| 142 | location: LOCATION, | |
| 143 | symbol: Symbols.Classy, | |
| 144 | arguments: Collections.List[Types.Type] | |
| 145 | ) -> Types.GENERIC => | |
| 146 | Types.MAYBE(location, symbol, arguments); | |
| 147 | ||
| 148 | short_description: string => Types.MAYBE.get_short_description(self); | |
| 149 | ||
| 150 | to_string() -> string => "{arguments[0]}?"; | |
| 151 | si | |
| 152 | ||
| 153 | class HYBRID_GENERIC_TYPE_WRAPPER: Types.GENERIC is | |
| 154 | _symbol_table: SYMBOL_TABLE; | |
| 155 | _dotnet_type: TYPE; | |
| 156 | _arguments: List[Type]; | |
| 157 | ||
| 158 | // _symbol: Symbols.GENERIC; | |
| 159 | ||
| 160 | symbol: Symbols.Symbol is | |
| 161 | // _symbol is lazily materialized on first access | |
| 162 | @suppress("presence-test-non-optional") | |
| 163 | if !_symbol? then | |
| 164 | materialize(); | |
| 165 | fi | |
| 166 | ||
| 167 | return _symbol; | |
| 168 | si | |
| 169 | ||
| 170 | init( | |
| 171 | symbol_table: SYMBOL_TABLE, | |
| 172 | dotnet_type: TYPE, | |
| 173 | arguments: List[Type] | |
| 174 | ) is | |
| 175 | assert arguments.count > 0 else "expected at least one type argument"; | |
| 176 | ||
| 177 | _symbol_table = symbol_table; | |
| 178 | _dotnet_type = dotnet_type; | |
| 179 | _arguments = arguments; | |
| 180 | si | |
| 181 | ||
| 182 | init( | |
| 183 | symbol_table: SYMBOL_TABLE, | |
| 184 | dotnet_type: TYPE, | |
| 185 | argument: Type | |
| 186 | ) is | |
| 187 | _symbol_table = symbol_table; | |
| 188 | _dotnet_type = dotnet_type; | |
| 189 | _arguments = LIST[Type]([argument]); | |
| 190 | si | |
| 191 | ||
| 192 | materialize() is | |
| 193 | let s = _symbol_table.get_symbol(_dotnet_type); | |
| 194 | ||
| 195 | let unspecialized = cast Symbols.Classy?(s)!; | |
| 196 | ||
| 197 | _symbol = create_symbol(unspecialized, _arguments); | |
| 198 | si | |
| 199 | ||
| 200 | create_symbol(unspecialized: Symbols.Classy, arguments: List[Types.Type]) -> Symbols.GENERIC => | |
| 201 | Symbols.GENERIC(Source.LOCATION.internal, unspecialized, arguments); | |
| 202 | si | |
| 203 | ||
| 204 | class HYBRID_ARRAY_TYPE_WRAPPER: HYBRID_GENERIC_TYPE_WRAPPER is | |
| 205 | short_description: string => Types.ARRAY.get_short_description(self); | |
| 206 | ||
| 207 | init( | |
| 208 | symbol_table: SYMBOL_TABLE, | |
| 209 | dotnet_type: TYPE, | |
| 210 | argument: Type | |
| 211 | ) is | |
| 212 | super.init( | |
| 213 | symbol_table, | |
| 214 | dotnet_type, | |
| 215 | argument | |
| 216 | ); | |
| 217 | si | |
| 218 | ||
| 219 | create(location: LOCATION, symbol: Symbols.Classy, arguments: Collections.List[Type]) -> Types.GENERIC => | |
| 220 | Types.ARRAY(location, symbol, arguments); | |
| 221 | ||
| 222 | to_string() -> string => Types.ARRAY.get_short_description(self); | |
| 223 | si | |
| 224 | ||
| 225 | class HYBRID_REFERENCE_TYPE_WRAPPER: HYBRID_GENERIC_TYPE_WRAPPER is | |
| 226 | short_description: string => Types.REFERENCE.get_short_description(self); | |
| 227 | ||
| 228 | init( | |
| 229 | symbol_table: SYMBOL_TABLE, | |
| 230 | dotnet_type: TYPE, | |
| 231 | argument: Type | |
| 232 | ) is | |
| 233 | super.init( | |
| 234 | symbol_table, | |
| 235 | dotnet_type, | |
| 236 | argument | |
| 237 | ); | |
| 238 | si | |
| 239 | ||
| 240 | create(location: LOCATION, symbol: Symbols.Classy, arguments: Collections.List[Type]) -> Types.GENERIC => | |
| 241 | Types.REFERENCE(location, symbol, arguments); | |
| 242 | ||
| 243 | to_string() -> string => Types.REFERENCE.get_short_description(self); | |
| 244 | si | |
| 245 | ||
| 246 | class HYBRID_POINTER_TYPE_WRAPPER: HYBRID_GENERIC_TYPE_WRAPPER is | |
| 247 | short_description: string => Types.POINTER.get_short_description(self); | |
| 248 | ||
| 249 | init( | |
| 250 | symbol_table: SYMBOL_TABLE, | |
| 251 | dotnet_type: TYPE, | |
| 252 | argument: Type | |
| 253 | ) is | |
| 254 | super.init( | |
| 255 | symbol_table, | |
| 256 | dotnet_type, | |
| 257 | argument | |
| 258 | ); | |
| 259 | si | |
| 260 | ||
| 261 | create(location: LOCATION, symbol: Symbols.Classy, arguments: Collections.List[Type]) -> Types.GENERIC => | |
| 262 | Types.POINTER(location, symbol, arguments); | |
| 263 | ||
| 264 | to_string() -> string => Types.POINTER.get_short_description(self); | |
| 265 | si | |
| 266 | si |