Skip to content
← Back

src/syntax/parsers/definitions/struct.ghul

1
namespace Syntax.Parsers.Definitions is
2
use Source;
3
4
class STRUCT(
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
variable_list_parser: Parser[Trees.Variables.LIST],
10
definition_list_parser: Parser[Trees.Definitions.LIST]
11
): Base[Trees.Definitions.STRUCT] is
12
super();
13
14
parse(context: CONTEXT) -> Trees.Definitions.STRUCT? is
15
let start = context.location;
16
context.in_classy = true;
17
context.global_indent = start.start_column;
18
19
try
20
let fail = false;
21
context.next_token(Lexical.TOKEN.STRUCT);
22
23
let identifier = identifier_parser.parse(context);
24
25
if !identifier? then
26
return null;
27
fi
28
29
let arguments: Trees.TypeExpressions.LIST? mut = null;
30
let ancestors: Trees.TypeExpressions.LIST? mut = null;
31
32
let is_poisoned mut = false;
33
34
if context.current.token == Lexical.TOKEN.SQUARE_OPEN then
35
context.next_token();
36
37
context.in_type_parameters = true;
38
arguments = type_list_parser.parse(context)!;
39
context.in_type_parameters = false;
40
arguments.check_no_reference_types(context.logger);
41
42
is_poisoned = arguments.is_poisoned;
43
44
if
45
!is_poisoned \/
46
context.current.token == Lexical.TOKEN.SQUARE_CLOSE
47
then
48
is_poisoned = !context.next_token(Lexical.TOKEN.SQUARE_CLOSE) \/ is_poisoned;
49
fi
50
fi
51
52
let primary_params: Trees.Variables.LIST? mut = null;
53
54
if context.current.token == Lexical.TOKEN.PAREN_OPEN then
55
context.next_token();
56
57
if context.current.token != Lexical.TOKEN.PAREN_CLOSE then
58
let previous_in_primary_ctor_params = context.in_primary_ctor_params;
59
context.in_primary_ctor_params = true;
60
try
61
primary_params = variable_list_parser.parse(context);
62
finally
63
context.in_primary_ctor_params = previous_in_primary_ctor_params;
64
yrt
65
66
if primary_params? then
67
for p in primary_params do
68
p.mark_argument();
69
od
70
71
is_poisoned = is_poisoned \/ primary_params.is_poisoned;
72
fi
73
else
74
primary_params = Trees.Variables.LIST(
75
context.location,
76
Collections.LIST[Trees.Variables.VARIABLE](0)
77
);
78
fi
79
80
is_poisoned = !context.next_token(Lexical.TOKEN.PAREN_CLOSE) \/ is_poisoned;
81
fi
82
83
if context.current.token == Lexical.TOKEN.COLON then
84
context.next_token();
85
ancestors = type_list_parser.parse(context)!;
86
ancestors.check_no_reference_types(context.logger);
87
88
is_poisoned = is_poisoned \/ ancestors.is_poisoned;
89
fi
90
91
let modifiers = modifier_list_parser.parse(context)!;
92
93
if primary_params? /\ context.current.token == Lexical.TOKEN.SEMICOLON then
94
let semicolon_end = context.location;
95
context.next_token();
96
97
let body = Trees.Definitions.LIST(LOCATION.internal, Collections.LIST[Trees.Definitions.Definition](0));
98
99
let result = Trees.Definitions.STRUCT(
100
start::semicolon_end,
101
identifier!,
102
arguments,
103
ancestors,
104
modifiers,
105
body
106
);
107
108
result.set_primary_params(primary_params);
109
110
if !fail then
111
return result;
112
fi
113
fi
114
115
let expect_body = !fail \/ context.current.token == Lexical.TOKEN.IS;
116
117
if expect_body /\ context.next_token(Lexical.TOKEN.IS) then
118
let body = definition_list_parser.parse(context)!;
119
120
let result = Trees.Definitions.STRUCT(
121
start::context.location,
122
identifier!,
123
arguments,
124
ancestors,
125
modifiers,
126
body
127
);
128
129
if primary_params? then
130
result.set_primary_params(primary_params);
131
fi
132
133
context.next_token(Lexical.TOKEN.SI);
134
135
if !fail then
136
return result;
137
fi
138
fi
139
140
finally
141
context.in_classy = false;
142
yrt
143
return null;
144
si
145
si
146
si