Landin library reference source

compiler/tests/fixtures/runtime/core-io-erased-system/main.ldn

1import core/io
2import hosted/io as hosted
3
4path_rules_code: () -> (code: i32) =
5    code = 10
6    mut scratch: [4]u8 = [91, 92, 93, 94]
7    empty: [1]u8 = [65]
8    mut empty_path: ptr u8 = addr scratch[0]
9    empty_path = io.terminate_path(empty[0..<0], scratch[0..<4])
10      else (problem)
11        if problem <> io.empty_path or scratch[0] <> 91
12          or scratch[1] <> 92 or scratch[2] <> 93 or scratch[3] <> 94
13        then
14            return
15        end if
16        empty_path
17    end
18    _ = empty_path
19    code = 11
20
21    with_nul: [3]u8 = [65, 0, 66]
22    mut nul_path: ptr u8 = addr scratch[0]
23    nul_path = io.terminate_path(with_nul[0..<3], scratch[0..<4])
24      else (problem)
25        if problem <> io.path_contains_nul or scratch[0] <> 91
26          or scratch[1] <> 92 or scratch[2] <> 93 or scratch[3] <> 94
27        then
28            return
29        end if
30        nul_path
31    end
32    _ = nul_path
33    code = 12
34
35    too_wide: [2]u8 = [65, 66]
36    mut short_scratch: [2]u8 = [81, 82]
37    mut long_path: ptr u8 = addr short_scratch[0]
38    long_path = io.terminate_path(too_wide[0..<2], short_scratch[0..<2])
39      else (problem)
40        if problem <> io.path_too_long or short_scratch[0] <> 81
41          or short_scratch[1] <> 82
42        then
43            return
44        end if
45        long_path
46    end
47    _ = long_path
48    code = 13
49
50    mut exact_scratch: [3]u8 = [71, 72, 73]
51    exact: ptr u8 = io.terminate_path(too_wide[0..<2],
52                                      exact_scratch[0..<3])
53      else (problem)
54        _ = problem
55        return
56    end
57    if exact <> addr exact_scratch[0] or exact_scratch[0] <> 65
58      or exact_scratch[1] <> 66 or exact_scratch[2] <> 0
59    then
60        return
61    end if
62    code = 14
63    mut right: [5]u8 = [65, 66, 67, 88, 88]
64    right_path: ptr u8 = io.terminate_path(right[0..<3], right[1..<5])
65      else (problem)
66        _ = problem
67        return
68    end
69    if right_path <> addr right[1] or right[1] <> 65 or right[2] <> 66
70      or right[3] <> 67 or right[4] <> 0
71    then
72        return
73    end if
74    code = 15
75    mut left: [5]u8 = [88, 65, 66, 67, 88]
76    left_path: ptr u8 = io.terminate_path(left[1..<4], left[0..<4])
77      else (problem)
78        _ = problem
79        return
80    end
81    if left_path <> addr left[0] or left[0] <> 65 or left[1] <> 66
82      or left[2] <> 67 or left[3] <> 0
83    then
84        return
85    end if
86    code = 16
87    mut same: [4]u8 = [65, 66, 67, 88]
88    same_path: ptr u8 = io.terminate_path(same[0..<3], same[0..<4])
89      else (problem)
90        _ = problem
91        return
92    end
93    if same_path <> addr same[0] or same[0] <> 65 or same[1] <> 66
94      or same[2] <> 67 or same[3] <> 0
95    then
96        return
97    end if
98    code = 17
99    mut invalid: [5]u8 = [65, 0, 67, 88, 88]
100    mut invalid_path: ptr u8 = addr invalid[1]
101    invalid_path = io.terminate_path(invalid[0..<3], invalid[1..<5])
102      else (problem)
103        if problem <> io.path_contains_nul or invalid[0] <> 65
104          or invalid[1] <> 0 or invalid[2] <> 67 or invalid[3] <> 88
105          or invalid[4] <> 88
106        then
107            return
108        end if
109        invalid_path
110    end
111    _ = invalid_path
112    code = 42
113end path_rules_code
114
115text_path_rules_code: (inout state: hosted.system) -> (code: i32) =
116    mut scratch: [4]u8 = [91, 92, 93, 94]
117    mut opened: io.file = io.out(state)
118    code = 32
119    opened = io.open_read_text(state, "", scratch[0..<4]) else (problem)
120        if problem <> io.empty_path or scratch[0] <> 91
121          or scratch[1] <> 92 or scratch[2] <> 93 or scratch[3] <> 94
122        then
123            return
124        end if
125        code = 33
126        io.out(state)
127    end
128    if code <> 33 then
129        return
130    end if
131
132    opened = io.open_read_text(state, "A\u{0}B", scratch[0..<4])
133      else (problem)
134        if problem <> io.path_contains_nul or scratch[0] <> 91
135          or scratch[1] <> 92 or scratch[2] <> 93 or scratch[3] <> 94
136        then
137            return
138        end if
139        code = 34
140        io.out(state)
141    end
142    if code <> 34 then
143        return
144    end if
145
146    opened = io.open_read_text(state, "ABCD", scratch[0..<4])
147      else (problem)
148        if problem <> io.path_too_long or scratch[0] <> 91
149          or scratch[1] <> 92 or scratch[2] <> 93 or scratch[3] <> 94
150        then
151            return
152        end if
153        code = 42
154        io.out(state)
155    end
156end text_path_rules_code
157
158no_second_argument: (state: any io.world) -> (yes: bool) =
159    second: usize = 1
160    unexpected := state.argument(second) else (problem)
161        yes = problem == io.no_argument
162        return
163    end
164    _ = unexpected.length
165    yes = false
166end no_second_argument
167
168missing_read_is_reported: (state: any io.world, path: ptr u8)
169                          -> (yes: bool) =
170    opened := state.open_read(path) else (problem)
171        yes = problem == io.not_found
172        return
173    end
174    state.close(opened) else (problem)
175        _ = problem
176    end
177    yes = false
178end missing_read_is_reported
179
180missing_write_is_reported: (state: any io.world, path: ptr u8)
181                           -> (yes: bool) =
182    opened := state.open_write(path) else (problem)
183        yes = problem == io.not_found
184        return
185    end
186    state.close(opened) else (problem)
187        _ = problem
188    end
189    yes = false
190end missing_write_is_reported
191
192denied_write_is_reported: (state: any io.world, path: ptr u8)
193                          -> (yes: bool) =
194    opened := state.open_write(path) else (problem)
195        yes = problem == io.no_access
196        return
197    end
198    state.close(opened) else (problem)
199        _ = problem
200    end
201    yes = false
202end denied_write_is_reported
203
204public main: () -> (code: i32) =
205    code = 1
206    path_code: i32 = path_rules_code()
207    if path_code <> 42 then
208        code = path_code
209        return
210    end if
211
212    mut host := hosted.host()
213    code = 2
214    if io.argument_count(host) <> 1 then
215        return
216    end if
217    source_state: ptr hosted.system = addr host
218    direct_index: usize = 0
219    direct_source := io.argument_at(source_state, direct_index) else (problem)
220        _ = problem
221        return
222    end
223    code = 3
224    if direct_source.length == 0 then
225        return
226    end if
227    text_path_code: i32 = text_path_rules_code(host)
228    if text_path_code <> 42 then
229        code = text_path_code
230        return
231    end if
232    mut world: any io.world = any(addr host)
233    code = 4
234    if world.argument_count() <> 1 then
235        return
236    end if
237
238    code = 5
239    first: usize = 0
240    source := world.argument(first) else (problem)
241        _ = problem
242        return
243    end
244    code = 6
245    if source.length == 0 then
246        return
247    end if
248    return when not no_second_argument(world)
249    code = 7
250
251    opened := world.open_read(source.data) else (problem)
252        _ = problem
253        return
254    end
255    code = 8
256    mut copied_opened: io.file = opened
257    mut input: [13]u8 = zeroed
258    count: usize = world.read(opened, input[0..<13]) else (problem)
259        _ = problem
260        return
261    end
262    code = 9
263    if count <> 13 or input[0] <> 112 or input[6] <> 32
264      or input[12] <> 10
265    then
266        return
267    end if
268    code = 14
269    eof: usize = world.read(opened, input[0..<13]) else (problem)
270        _ = problem
271        return
272    end
273    if eof <> 0 then
274        return
275    end if
276    code = 15
277    world.close(opened) else (problem)
278        _ = problem
279        return
280    end
281    code = 16
282    world.close(copied_opened) else (problem)
283        if problem <> io.io_failed then
284            return
285        end if
286        copied_opened = world.out()
287    end
288    code = 17
289
290    mut generic_host := hosted.host()
291    mut path_scratch: [30]u8 = zeroed
292    code = 18
293    output := io.open_write_text(generic_host,
294                                 "/tmp/landin-r420-io-world.out",
295                                 path_scratch[0..<30]) else (problem)
296        _ = problem
297        return
298    end
299    code = 19
300    payload: [7]u8 = [76, 97, 110, 100, 105, 110, 10]
301    world.write(output, payload[0..<0]) else (problem)
302        _ = problem
303        return
304    end
305    world.write(output, payload[0..<7]) else (problem)
306        _ = problem
307        return
308    end
309    code = 20
310    world.close(output) else (problem)
311        _ = problem
312        return
313    end
314    code = 21
315
316    mut second_scratch: [30]u8 = zeroed
317    verify := io.open_read_text(generic_host,
318                                "/tmp/landin-r420-io-world.out",
319                                second_scratch[0..<30]) else (problem)
320        _ = problem
321        return
322    end
323    code = 22
324    mut result: [8]u8 = zeroed
325    result_length: usize = io.read(generic_host, verify, result[0..<8])
326      else (problem)
327        _ = problem
328        return
329    end
330    code = 23
331    io.close(generic_host, verify) else (problem)
332        _ = problem
333        return
334    end
335    code = 24
336    if result_length <> 7 or result[0] <> 76 or result[1] <> 97
337      or result[2] <> 110 or result[3] <> 100 or result[4] <> 105
338      or result[5] <> 110 or result[6] <> 10
339    then
340        return
341    end if
342    code = 25
343
344    missing: [45]u8 =
345        [47, 100, 101, 102, 105, 110, 105, 116, 101, 108, 121, 45,
346         110, 111, 116, 45, 97, 45, 108, 97, 110, 100, 105, 110, 45,
347         100, 105, 114, 101, 99, 116, 111, 114, 121, 45, 114, 52, 50,
348         48, 47, 102, 105, 108, 101, 0]
349    missing_path: ptr u8 = addr missing[0]
350    return when not missing_read_is_reported(world, missing_path)
351    code = 26
352    return when not missing_write_is_reported(world, missing_path)
353    code = 27
354
355    denied: [24]u8 =
356        [47, 115, 121, 115, 47, 108, 97, 110, 100, 105, 110, 45,
357         114, 52, 50, 48, 45, 100, 101, 110, 105, 101, 100, 0]
358    denied_path: ptr u8 = addr denied[0]
359    return when not denied_write_is_reported(world, denied_path)
360    code = 28
361
362    full_name: [10]u8 = [47, 100, 101, 118, 47, 102, 117, 108, 108, 0]
363    full_path: ptr u8 = addr full_name[0]
364    full := world.open_write(full_path) else (problem)
365        _ = problem
366        return
367    end
368    code = 29
369    world.write(full, payload[0..<0]) else (problem)
370        _ = problem
371        return
372    end
373    mut saw_write_failure: bool = false
374    world.write(full, payload[0..<7]) else (problem)
375        if problem <> io.io_failed then
376            return
377        end if
378        saw_write_failure = true
379    end
380    return when not saw_write_failure
381    code = 30
382    world.close(full) else (problem)
383        _ = problem
384        return
385    end
386    code = 31
387
388    output_stream := world.out()
389    error_stream := world.err()
390    world.write(error_stream, payload[0..<0]) else (problem)
391        _ = problem
392        return
393    end
394    okay: [3]u8 = [79, 75, 10]
395    world.write(output_stream, okay[0..<3]) else (problem)
396        _ = problem
397        return
398    end
399    code = 42
400end main