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
context.in_generic_parameter_list = true
39
arguments = type_list_parser.parse(context)!
40
context.in_type_parameters = false
41
context.in_generic_parameter_list = false
42
arguments.check_no_reference_types(context.logger)
43
44
is_poisoned = arguments.is_poisoned
45
46
if
47
!is_poisoned \/
48
context.current.token == Lexical.TOKEN.SQUARE_CLOSE
49
then
50
is_poisoned = !context.next_token(Lexical.TOKEN.SQUARE_CLOSE) \/ is_poisoned
51
fi
52
fi
53
54
let primary_params: Trees.Variables.LIST? mut = null
55
56
if context.current.token == Lexical.TOKEN.PAREN_OPEN then
57
context.next_token()
58
59
if context.current.token != Lexical.TOKEN.PAREN_CLOSE then
60
let previous_in_primary_ctor_params = context.in_primary_ctor_params
61
context.in_primary_ctor_params = true
62
try
63
primary_params = variable_list_parser.parse(context)
64
finally
65
context.in_primary_ctor_params = previous_in_primary_ctor_params
66
yrt
67
68
if primary_params? then
69
for p in primary_params do
70
p.mark_argument()
71
od
72
73
is_poisoned = is_poisoned \/ primary_params.is_poisoned
74
fi
75
else
76
primary_params = Trees.Variables.LIST(
77
context.location,
78
Collections.LIST[Trees.Variables.VARIABLE](0)
79
)
80
fi
81
82
is_poisoned = !context.next_token(Lexical.TOKEN.PAREN_CLOSE) \/ is_poisoned
83
fi
84
85
if context.current.token == Lexical.TOKEN.COLON then
86
context.next_token()
87
ancestors = type_list_parser.parse(context)!
88
ancestors.check_no_reference_types(context.logger)
89
90
is_poisoned = is_poisoned \/ ancestors.is_poisoned
91
fi
92
93
let modifiers = modifier_list_parser.parse(context)!
94
95
if
96
primary_params? /\
97
(
98
context.current.token == Lexical.TOKEN.SEMICOLON \/
99
(context.at_inferred_terminator /\ context.current.token != Lexical.TOKEN.IS)
100
)
101
then
102
let semicolon_end = context.location
103
104
if context.current.token == Lexical.TOKEN.SEMICOLON then
105
let semicolon = context.current
106
context.next_token()
107
context.note_written_terminator(semicolon)
108
else
109
context.note_inferred_terminator()
110
fi
111
112
let body = Trees.Definitions.LIST(LOCATION.internal, Collections.LIST[Trees.Definitions.Definition](0))
113
114
let result = Trees.Definitions.STRUCT(
115
start::semicolon_end,
116
identifier!,
117
arguments,
118
ancestors,
119
modifiers,
120
body
121
)
122
123
result.set_primary_params(primary_params)
124
125
if !fail then
126
return result
127
fi
128
fi
129
130
let expect_body = !fail \/ context.current.token == Lexical.TOKEN.IS
131
132
if expect_body /\ context.next_token(Lexical.TOKEN.IS) then
133
let use open = context.open_construct(Lexical.TOKEN.SI)
134
135
let body = definition_list_parser.parse(context)!
136
137
let result = Trees.Definitions.STRUCT(
138
start::context.location,
139
identifier!,
140
arguments,
141
ancestors,
142
modifiers,
143
body
144
)
145
146
if primary_params? then
147
result.set_primary_params(primary_params)
148
fi
149
150
context.expect_closer(Lexical.TOKEN.SI)
151
152
if !fail then
153
return result
154
fi
155
fi
156
157
finally
158
context.in_classy = false
159
yrt
160
return null
161
si
162
si
163
si