forked from joelvaneenwyk/language84
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbufio.84
More file actions
140 lines (117 loc) · 2.67 KB
/
Copy pathbufio.84
File metadata and controls
140 lines (117 loc) · 2.67 KB
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
{
: new_writer
: new_writer2
: write_all
: write_byte
: write
: flush
: with_writer
}
Where
Define (with_writer fd size func)
Let w (new_writer2 fd size)
In
Begin {
(func w)
(IO.flush w)
}
Where
Define (new_writer2 fd size)
Define (write w bytes start size)
(write w.state bytes start size)
Define (write_all w bytes)
(write_all w.state bytes)
Define (write_byte w byte)
(write_byte w.state byte)
Define (flush w)
(flush w.state)
In
{
: interface {: write : write_all : write_byte : flush}
: state (new_writer fd size)
}
Where
Define (write_all w bytes)
(write w bytes 0 (CHUNK.size bytes))
Where
Define (write_byte w byte)
Begin {
When [(fetch_top w) = (size w)] {
(flush w)
}
Begin {
Let top (fetch_top w)
(CHUNK.store_byte w [8 + top] byte)
(store_top w [top + 1])
}
}
Define (write w bytes start count)
Let fd (fetch_fd w)
Let size (size w)
In
Iterate {start count}
Let top (fetch_top w)
In
Let room [size - top]
In
Begin Cond {
| [count > room]
(Return
Begin Cond {
| [top = 0]
Let r (OS.write fd bytes start count)
When [r <= 0] {
(OS.die "Failed to write bytes.")
}
(Continue [start + r] [count - r])
| True
(CHUNK.store_bytes w [8 + top] bytes start room)
(store_top w size)
(flush w)
(Continue [start + room] [count - room])
})
| True
(CHUNK.store_bytes w [8 + top] bytes start count)
(store_top w [top + count])
}
Where
Define (new_writer fd size)
Begin {
Let w (alloc size)
(init w fd)
(Return w)
}
Define (flush w)
Let fd (fetch_fd w)
Let top (fetch_top w)
In
When [top > 0] {
Let r (OS.write fd w 8 top)
When [r != top] {
(OS.die "Failed to flush buffer.")
}
(store_top w 0)
}
Where
Define (alloc size)
(CHUNK.new [8 + size])
Define (init w fd)
Begin {
(store_fd w fd)
}
Where
Define (store_fd w fd)
(CHUNK.store_uint32 w 0 fd)
Define (fetch_fd w)
(CHUNK.fetch_uint32 w 0)
Define (store_top w top)
(CHUNK.store_uint32 w 4 top)
Define (fetch_top w)
(CHUNK.fetch_uint32 w 4)
Define (size w)
[(CHUNK.size w) - 8]
Where
Let CHUNK Package "chunk"
Let IO Package "io"
Let OS Package "os"
Let STDIO Package "stdio"