Skip to content
← Back

src/syntax/parsers/definitions/impl.ghul

1
namespace Syntax.Parsers.Definitions is
2
use Source
3
4
// impl <Interface> for <Target>[<params>] is <members> si
5
// Injects an interface implementation into an already-declared type. The
6
// interface's type parameters are the target's own, so they are written on
7
// the target (`for List[T]`), not as a separate binder.
8
class IMPL(
9
identifier_qualified_parser: Parser[Trees.Identifiers.Identifier],
10
type_parser: Parser[Trees.TypeExpressions.TypeExpression],
11
type_list_parser: Parser[Trees.TypeExpressions.LIST],
12
modifier_list_parser: Parser[Trees.Modifiers.LIST],
13
definition_list_parser: Parser[Trees.Definitions.LIST]
14
): Base[Trees.Definitions.IMPL] is
15
super()
16
17
parse(context: CONTEXT) -> Trees.Definitions.IMPL? is
18
let start = context.location
19
context.in_classy = true
20
context.global_indent = start.start_column
21
22
try
23
context.next_token(Lexical.TOKEN.IMPL)
24
25
let interface = type_parser.parse(context)
26
27
if interface == null then
28
return null
29
fi
30
31
let is_poisoned mut = interface.is_poisoned
32
33
is_poisoned = !context.next_token(Lexical.TOKEN.FOR) \/ is_poisoned
34
35
let identifier = identifier_qualified_parser.parse(context)
36
37
if !identifier? then
38
return null
39
fi
40
41
let arguments: Trees.TypeExpressions.LIST? mut = null
42
43
if context.current.token == Lexical.TOKEN.SQUARE_OPEN then
44
context.next_token()
45
46
context.in_type_parameters = true
47
context.in_generic_parameter_list = true
48
arguments = type_list_parser.parse(context)!
49
context.in_type_parameters = false
50
context.in_generic_parameter_list = false
51
arguments.check_no_reference_types(context.logger)
52
53
is_poisoned = arguments.is_poisoned \/ is_poisoned
54
55
if
56
!arguments.is_poisoned \/
57
context.current.token == Lexical.TOKEN.SQUARE_CLOSE
58
then
59
is_poisoned = !context.next_token(Lexical.TOKEN.SQUARE_CLOSE) \/ is_poisoned
60
fi
61
fi
62
63
let ancestors =
64
Trees.TypeExpressions.LIST(
65
interface.location,
66
[interface]
67
)
68
69
let modifiers = modifier_list_parser.parse(context)!
70
71
let expect_body = !is_poisoned \/ context.current.token == Lexical.TOKEN.IS
72
let have_body mut = false
73
74
let body: Trees.Definitions.LIST mut
75
76
if expect_body /\ context.next_token(Lexical.TOKEN.IS) then
77
let use open = context.open_construct(Lexical.TOKEN.SI)
78
79
body = definition_list_parser.parse(context)!
80
have_body = true
81
else
82
body = Trees.Definitions.LIST(LOCATION.internal, Collections.LIST[Trees.Definitions.Definition](0))
83
is_poisoned = true
84
fi
85
86
let result = Trees.Definitions.IMPL(
87
start::context.location,
88
identifier,
89
arguments,
90
ancestors,
91
modifiers,
92
body
93
)
94
95
result.poison(is_poisoned)
96
97
if have_body then
98
context.expect_closer(Lexical.TOKEN.SI)
99
fi
100
101
return result
102
finally
103
context.in_classy = false
104
yrt
105
si
106
si
107
si