Skip to content
← Back

src/syntax/parsers/definitions/trait.ghul

1
namespace Syntax.Parsers.Definitions is
2
use Source;
3
4
class TRAIT(
5
identifier_parser: Parser[Trees.Identifiers.Identifier],
6
type_parser: Parser[Trees.TypeExpressions.TypeExpression],
7
type_list_parser: Parser[Trees.TypeExpressions.LIST],
8
modifier_list_parser: Parser[Trees.Modifiers.LIST],
9
definition_list_parser: Parser[Trees.Definitions.LIST]
10
): Base[Trees.Definitions.TRAIT] is
11
super();
12
13
parse(context: CONTEXT) -> Trees.Definitions.TRAIT? is
14
let start = context.location;
15
context.in_classy = true;
16
context.global_indent = start.start_column;
17
18
try
19
context.next_token(Lexical.TOKEN.TRAIT);
20
let identifier = identifier_parser.parse(context);
21
22
let is_poisoned mut = false;
23
24
if !identifier? then
25
return null;
26
fi
27
28
let arguments: Trees.TypeExpressions.LIST? mut = null;
29
let ancestors: Trees.TypeExpressions.LIST? mut = null;
30
31
if context.current.token == Lexical.TOKEN.SQUARE_OPEN then
32
context.next_token();
33
34
context.in_type_parameters = true;
35
arguments = type_list_parser.parse(context)!;
36
context.in_type_parameters = false;
37
arguments.check_no_reference_types(context.logger);
38
39
is_poisoned = arguments.is_poisoned;
40
41
if
42
!is_poisoned \/
43
context.current.token == Lexical.TOKEN.SQUARE_CLOSE
44
then
45
is_poisoned = !context.next_token(Lexical.TOKEN.SQUARE_CLOSE) \/ is_poisoned;
46
fi
47
fi
48
49
if context.current.token == Lexical.TOKEN.COLON then
50
context.next_token();
51
ancestors = type_list_parser.parse(context)!;
52
ancestors.check_no_reference_types(context.logger);
53
54
is_poisoned = is_poisoned \/ ancestors.is_poisoned;
55
fi
56
57
let modifiers = modifier_list_parser.parse(context)!;
58
59
let expect_body = !is_poisoned \/ context.current.token == Lexical.TOKEN.IS;
60
let have_body mut = false;
61
62
let body: Trees.Definitions.LIST mut;
63
64
if expect_body /\ context.next_token(Lexical.TOKEN.IS) then
65
let in_trait = context.in_trait;
66
context.in_trait = true;
67
68
body = definition_list_parser.parse(context)!;
69
70
context.in_trait = in_trait;
71
72
have_body = true;
73
else
74
body = Trees.Definitions.LIST(LOCATION.internal, Collections.LIST[Trees.Definitions.Definition](0));
75
is_poisoned = true;
76
fi
77
78
let result = Trees.Definitions.TRAIT(
79
start::context.location,
80
identifier,
81
arguments,
82
ancestors,
83
modifiers,
84
body
85
);
86
87
result.poison(is_poisoned);
88
89
if have_body then
90
context.next_token(Lexical.TOKEN.SI);
91
fi
92
93
return result;
94
finally
95
context.in_classy = false;
96
yrt
97
si
98
si
99
si