-
-
Notifications
You must be signed in to change notification settings - Fork 372
/
control.pir
200 lines (160 loc) Β· 3.78 KB
/
control.pir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
=head1 NAME
src/builtins/control.pir - control flow related functions
=head1 Functions
=over 4
=cut
.include 'except_types.pasm'
.include 'except_severity.pasm'
=item die
=cut
.sub '&die'
.param pmc list :slurpy
.local string message
.local pmc p6ex
.local pmc ex
message = join '', list
if message > '' goto have_message
message = "Died\n"
have_message:
p6ex = new ['Perl6Exception']
ex = root_new ['parrot';'Exception']
ex = message
ex['severity'] = .EXCEPT_FATAL
ex['type'] = .CONTROL_ERROR
setattribute p6ex, '$!exception', ex
set_global '$!', p6ex
throw ex
.return ()
.end
=item fail
=cut
# XXX Need to throw a Failure, not a Mu
# XXX Need to check for 'use fatal'
.sub '&fail'
.param pmc value :optional
.param int has_value :opt_flag
.local pmc ex, p6ex, failure
ex = root_new ['parrot';'Exception']
$P0 = get_hll_global 'Exception'
p6ex = $P0.'new'(ex)
unless has_value goto no_value
ex['payload'] = value
$S0 = value
ex['message'] = value
no_value:
$P0 = get_hll_global 'Failure'
failure = $P0.'new'(p6ex)
ex = root_new ['parrot';'Exception']
ex['payload'] = failure
ex['severity'] = .EXCEPT_ERROR
ex['type'] = .CONTROL_RETURN
throw ex
.end
=item continue
=cut
.sub '&continue'
.local pmc ex, p6ex
ex = root_new ['parrot';'Exception']
ex['severity'] = .EXCEPT_NORMAL
ex['type'] = .CONTROL_CONTINUE
p6ex = new ['Perl6Exception']
setattribute p6ex, '$!exception', ex
set_global '$!', p6ex
throw ex
.end
=item break
=cut
.sub '&break'
.param pmc arg :optional
.param int has_arg :opt_flag
.local pmc e, p6ex
e = root_new ['parrot';'Exception']
e['severity'] = .EXCEPT_NORMAL
e['type'] = .CONTROL_BREAK
unless has_arg, no_arg
e['payload'] = arg
no_arg:
p6ex = new ['Perl6Exception']
setattribute p6ex, '$!exception', e
set_global '$!', p6ex
throw e
.end
=item next
=cut
.sub '&next'
.local pmc e, p6ex
e = root_new ['parrot';'Exception']
e['severity'] = .EXCEPT_NORMAL
e['type'] = .CONTROL_LOOP_NEXT
p6ex = new ['Perl6Exception']
setattribute p6ex, '$!exception', e
set_global '$!', p6ex
throw e
.end
=item redo
=cut
.sub '&redo'
.local pmc e, p6ex
e = root_new ['parrot';'Exception']
e['severity'] = .EXCEPT_NORMAL
e['type'] = .CONTROL_LOOP_REDO
p6ex = new ['Perl6Exception']
setattribute p6ex, '$!exception', e
set_global '$!', p6ex
throw e
.end
=item last
=cut
.sub '&last'
.local pmc e, p6ex
e = root_new ['parrot';'Exception']
e['severity'] = .EXCEPT_NORMAL
e['type'] = .CONTROL_LOOP_LAST
p6ex = new ['Perl6Exception']
setattribute p6ex, '$!exception', e
set_global '$!', p6ex
throw e
.end
=item take
=cut
.sub '&take'
.param pmc value
.local pmc ex, p6ex
ex = root_new ['parrot';'Exception']
ex['type'] = .CONTROL_TAKE
ex['severity'] = .EXCEPT_NORMAL
ex['message'] = 'take without gather'
setattribute ex, 'payload', value
p6ex = new ['Perl6Exception']
setattribute p6ex, '$!exception', ex
set_global '$!', p6ex
throw ex
.return (value)
.end
=item !GATHER
=cut
.sub '!GATHER'
.param pmc block
.local pmc true, array, eh
true = get_hll_global 'True'
array = new ['Array']
setprop array, "rw", true
setprop array, "flatten", true
eh = root_new ['parrot';'ExceptionHandler']
eh.'handle_types'(.CONTROL_TAKE)
set_addr eh, handler
push_eh eh
block()
pop_eh
.return (array)
handler:
.local pmc exception, continuation
.local string message
.get_results(exception)
continuation = exception['resume']
$P0 = exception['payload']
array.'push'($P0)
continuation()
.end
=back
=cut