Skip to content
← Back

src/semantic/pointer_sized_decimal_bridge.ghul

1
namespace Semantic is
2
use Types.Type
3
4
// System.Decimal declares a conversion for each of the fixed-width
5
// integers but none for a pointer-sized one, so a cast between the
6
// two has no single step to take. It goes through the 64-bit integer
7
// of the same signedness, which Decimal does declare a conversion
8
// for and which a `conv` opcode reaches from the pointer-sized type.
9
//
10
// Held apart from the casting itself because the rule is consulted
11
// twice - once to decide the cast is legal and once to perform it -
12
// and the two answers have to be the same one.
13
class POINTER_SIZED_DECIMAL_BRIDGE(_innate_symbol_lookup: Lookups.InnateSymbolLookup) is
14
super()
15
16
// The type to convert through, or null when the pair needs no
17
// bridge. Null for a pair that is already one step, and null
18
// once either side is the bridge type itself, which is what
19
// stops the two-step from reapplying to its own halves.
20
find(source: Type?, target: Type?) -> Type? is
21
if !source? \/ !target? then
22
return null
23
fi
24
25
let decimal_type = _innate_symbol_lookup.get_decimal_type()
26
27
let source_is_decimal = source.matches(decimal_type)
28
let target_is_decimal = target.matches(decimal_type)
29
30
if source_is_decimal == target_is_decimal then
31
return null
32
fi
33
34
let other = if source_is_decimal then target else source fi
35
36
if other.matches(_innate_symbol_lookup.get_word_type()) then
37
return _innate_symbol_lookup.get_long_type()
38
fi
39
40
if other.matches(_innate_symbol_lookup.get_uword_type()) then
41
return _innate_symbol_lookup.get_ulong_type()
42
fi
43
44
return null
45
si
46
si
47
si