impl.bend
bend-stdio-pipes@0.2.0.0 · 103 lines · 10 definitions
1
2
3
4
5import Base
6
7
8
9
10
11def stdin() -> IO(File):
12 import "./std.c"
13 import "./std.js"
14
15
16
17
18
19def open(
20 program: String,
21 args: List<String>
22) -> IO(Result<&1, &1, U32 & String, U32 & (File & File)>):
23 import "./open.c"
24 import "./open.js"
25
26
27
28
29def kill(pid: U32) -> IO(Result<&1, &1, U32 & String, Unit>):
30 import "./open.c"
31 import "./open.js"
32
33
34def read_line.peeked(
35 next: File & Result<&1, &1, U32 & String, String>,
36 text: String
37) -> File
38 & Result<&1, &1, U32 & String, Maybe<String>>:
39 match next:
40 case (file, Fail{error}):
41 (file, Fail{error})
42 case (file, Done{SNil{}}):
43 (file, Done{Some{text}})
44 case (file, Done{SCon{_, _}}):
45 (file, Fail{(7, "a line is longer than its cap")})
46
47
48def read_line.unended(+piece: String) -> String:
49 +line = String.take(piece, Nat.sub(String.length(piece), 1n))
50 Bool.pick(
51 String,
52 String.ends_with(line, "\r"),
53 String.take(line, Nat.sub(String.length(line), 1n)),
54 line
55 )
56
57def read_line.if(
58 file: File,
59 ended: Bool,
60 piece: String
61) -> IO(File & Result<&1, &1, U32 & String, Maybe<String>>):
62 match ended:
63 case True{}:
64 IO.pure(
65 File & Result<&1, &1, U32 & String, Maybe<String>>,
66 (file, Done{Some{read_line.unended(piece)}})
67 )
68 case False{}:
69 do IO<File & Result<&1, &1, U32 & String, Maybe<String>>>:
70 next: File & Result<&1, &1, U32 & String, String> <- File.read_line(file, 1)
71 return read_line.peeked(next, piece)
72
73def read_line.got(
74 got: File & Result<&1, &1, U32 & String, String>
75) -> IO(File & Result<&1, &1, U32 & String, Maybe<String>>):
76 match got:
77 case (file, Fail{error}):
78 IO.pure(File & Result<&1, &1, U32 & String, Maybe<String>>, (file, Fail{error}))
79 case (file, Done{SNil{}}):
80 IO.pure(File & Result<&1, &1, U32 & String, Maybe<String>>, (file, Done{None{}}))
81 case (file, Done{SCon{h, t}}):
82 +piece: String = SCon{h, t}
83 read_line.if(file, String.ends_with(piece, "\n"), piece)
84
85
86def read_line(file: File, max: U32) -> IO(File & Result<&1, &1, U32 & String, Maybe<String>>):
87 IO.bind(
88 File & Result<&1, &1, U32 & String, String>,
89 File & Result<&1, &1, U32 & String, Maybe<String>>,
90 File.read_line(file, max),
91 read_line.got
92 )
93
94def write_lines.text(lines: List<String>) -> String:
95 match lines:
96 case Nil{}:
97 ""
98 case Con{line, rest}:
99 line ++ "\n" ++ write_lines.text(rest)
100
101
102def write_lines(file: File, lines: List<String>) -> IO(File & Result<&1, &1, U32 & String, Unit>):
103 File.write(file, write_lines.text(lines))