@@ -24,6 +24,12 @@ record Signed[A](raw: A)
24
24
/// Bits
25
25
type Bit { B0(); B1() }
26
26
27
+ /// not on Bits
28
+ def not(b: Bit): Bit = b match {
29
+ case B0() => B1()
30
+ case B1() => B0()
31
+ }
32
+
27
33
/// Splices allowed in hex/byte stream literals
28
34
effect HexSplices = {
29
35
splice[Char], splice[String],
@@ -89,7 +95,10 @@ def signedBytesLE(int: Int): Unit / emit[Byte] = signedBytesLE(int, 4)
89
95
/// emit bytes of the given int as 4 bytes (in 2s-complement) in big-endian byte order
90
96
def signedBytesBE(int: Int): Unit / emit[Byte] = signedBytesBE(int, 4)
91
97
98
+ /// emit bits of the given int as 32 Bits in big-endian bit order
92
99
def bitsBE(int: Int): Unit / emit[Bit] = bitsBE(int, 32)
100
+
101
+ /// collect bits in big-endian bit order into an Int
93
102
def collectBitsBE{ body: => Unit / emit[Bit] }: Int = {
94
103
var res = 0
95
104
try body() with emit[Bit] { b =>
@@ -101,11 +110,10 @@ def collectBitsBE{ body: => Unit / emit[Bit] }: Int = {
101
110
}
102
111
res
103
112
}
104
- def not(b: Bit): Bit = b match {
105
- case B0() => B1()
106
- case B1() => B0()
107
- }
113
+
114
+ /// bitwise not on integers
108
115
def bitwiseNot(n: Int): Int = {
116
+ // TODO currently implemented in Effekt, should use extern ?
109
117
collectBitsBE{
110
118
try bitsBE(n) with emit[Bit]{ b => resume(do emit(not(b))) }
111
119
}
@@ -114,6 +122,8 @@ def bitwiseNot(n: Int): Int = {
114
122
// Splicers
115
123
// --------
116
124
125
+ /// Splicer to emit the bytes in hex notation given, plus evenutal splices
126
+ /// Ignores whitespace
117
127
def hex{ body: => Unit / { literal, HexSplices } }: Unit / emit[Byte] = {
118
128
try {
119
129
try {
@@ -153,6 +163,7 @@ def hex{ body: => Unit / { literal, HexSplices } }: Unit / emit[Byte] = {
153
163
with splice[OfWidth[BE[Signed[Int]]]] { w => signedBytesBE(w.raw.raw.raw, w.width); resume(()) }
154
164
}
155
165
166
+ /// convert the given hex notation to an integer (big-endian)
156
167
def x{ body: => Unit / { literal, HexSplices } }: Int = {
157
168
var res = 0
158
169
for[Byte]{ hex{body} }{ v => res = res * 256 + v.toInt }
@@ -161,8 +172,16 @@ def x{ body: => Unit / { literal, HexSplices } }: Int = {
161
172
162
173
// Counting and padding
163
174
// --------------------
175
+ // TODO could also be part of stream library
176
+
177
+ /// Request padding to a multiple of fac, by calling gen for each
164
178
effect pad[A](fac: Int){ gen: => A }: Unit
179
+
180
+ /// get current position in stream
165
181
effect getPos(): Int
182
+
183
+ /// Track position in stream, starting with init
184
+ /// Handles getPos and pad
166
185
def tracking[A](init: Int){ body: => Unit / { emit[A], getPos, pad[A] } }: Unit / emit[A] = {
167
186
var n = init
168
187
try body()
@@ -177,6 +196,9 @@ def tracking[A](init: Int){ body: => Unit / { emit[A], getPos, pad[A] } }: Unit
177
196
}
178
197
}
179
198
}
199
+
200
+ /// Track how many bytes were emitted
201
+ /// Handles getPos and pad
180
202
def tracking[A]{ body: => Unit / { emit[A], getPos, pad[A] } }: Unit / emit[A] =
181
203
tracking[A](0){body}
182
204
0 commit comments