Skip to content
← Back

src/semantic/types/tuple.ghul

1
namespace Semantic.Types is
2
use Source.LOCATION
3
4
use Logging
5
6
use Ghul.Pipes
7
8
class TUPLE: GENERIC is
9
names: Collections.List[string?]?
10
11
tuple_element_names: Collections.List[string?]? => names
12
13
short_description: string => get_short_description(self, names, false)
14
15
// Build an element-name list of exactly `arity` entries from
16
// the leading entries of a flattened TupleElementNamesAttribute
17
// array, padding with null.
18
take_element_names(names: Collections.List[string?]?, arity: int) -> Collections.List[string?]? static is
19
if !names? then
20
return null
21
fi
22
23
let result = Collections.LIST[string?]()
24
25
for i in 0..arity do
26
result.add(if i < names.count then names[i] else null fi)
27
od
28
29
return result
30
si
31
32
33
get_short_description(tuple: Type, names: Collections.List[string?]?) -> string static =>
34
get_short_description(tuple, names, false)
35
36
// Qualified renders each element as it would be written where the
37
// tuple is read, scope-relative; the short form names each bare.
38
get_short_description(tuple: Type, names: Collections.List[string?]?, qualified: bool) -> string static is
39
let args = tuple.arguments
40
41
assert args |> all(a => a?) else "tuple at least one null argument"
42
43
let element = (i: int) -> string => if qualified then "{args[i]}" else args[i].short_description fi
44
45
return "({(0..args.count) |> map(i => "{_get_element_name(names, i)}{element(i)}") |> join()})"
46
si
47
48
_get_element_name(names: Collections.List[string?]?, index: int) -> string static =>
49
if names? /\ index < names.count /\ names[index]? /\ !Symbols.Symbol.is_positional_member_name(names[index]) then
50
if Lexical.TOKENIZER.is_reserved_word(names[index]) then
51
"`{names[index]}: "
52
else
53
"{names[index]}: "
54
fi
55
else
56
""
57
fi
58
59
init(
60
location: LOCATION,
61
symbol: Symbols.Classy,
62
arguments: Collections.List[Type],
63
names: Collections.List[string?]?
64
) is
65
super.init(Symbols.TUPLE(location, symbol, arguments, names))
66
67
self.names = names
68
si
69
70
create(
71
location: LOCATION,
72
symbol: Symbols.Classy,
73
arguments: Collections.List[Type]
74
) -> GENERIC =>
75
TUPLE(location, symbol, arguments, names)
76
77
apply_tuple_element_names(new_names: Collections.List[string?]) -> Type =>
78
if let generic_symbol = cast Symbols.GENERIC?(symbol) then
79
TUPLE(LOCATION.internal, generic_symbol.symbol, arguments, take_element_names(new_names, arguments.count))
80
else
81
self
82
fi
83
84
to_string() -> string => get_short_description(self, names, true)
85
si
86
si