compiler/ lib/ examples/ std/ arch/ rv64/ tests/ abi.sizes.rad 3.4 KiB aggregate.return.rad 4.0 KiB arith.assignment.rad 580 B arith.basic.rad 176 B arith.modulo.rad 96 B arith.subword.rad 3.8 KiB arith.sum.rad 177 B arith.w64.rad 4.1 KiB array.assign.rad 221 B array.bounds.check.rad 321 B array.index.assign.rad 367 B array.index.rad 249 B array.length.rad 262 B array.math.rad 1.2 KiB array.nested.assign.rad 319 B array.nested.rad 325 B array.record.elements.rad 1.7 KiB array.repeat.edge.rad 548 B array.repeat.rad 828 B array.return.rad 330 B array.slice.empty.rad 108 B array.slice.gen.end.rad 126 B array.slice.gen.index.rad 139 B array.slice.gen.open.rad 125 B array.slice.gen.start.end.rad 127 B array.slice.gen.start.rad 126 B array.slice.rad 759 B as.precedence.rad 212 B assert.basic.rad 387 B assert.fail.rad 138 B assert.false.rad 140 B assert.true.rad 100 B assign.mutable.rad 6.1 KiB assign.rad 129 B assign.shadow.mutable.rad 461 B binop.bitwise.rad 1.2 KiB binop.cmp.rad 426 B bool.comparison.array.rad 688 B bool.comparison.nested.gen.rad 1.0 KiB bool.comparison.opt.rad 905 B bool.comparison.record.gen.rad 1.0 KiB bool.comparison.record.rad 1.1 KiB bool.comparison.slice.gen.rad 157 B bool.comparison.slice.rad 4.1 KiB bool.comparison.slice.record.gen.rad 2.0 KiB bool.comparison.slice.union.gen.rad 2.5 KiB bool.comparison.union.ctor.rad 690 B bool.comparison.union.gen.rad 1.2 KiB bool.comparison.union.record.gen.rad 1.5 KiB bool.comparison.union.simple.gen.rad 281 B bool.operators.complex.rad 384 B bool.operators.rad 831 B bool.short.circuit.rad 2.3 KiB bool.simple.rad 194 B bool.values.rad 772 B builtin.size.align.rad 1.3 KiB builtin.sliceof.mut.rad 606 B builtin.sliceof.rad 505 B call.arg.clobber.rad 717 B call.basic.rad 241 B call.clobber.rad 462 B cast.same.size.rad 1.0 KiB casting.numbers.rad 1.5 KiB char.literal.rad 165 B compound.assign.field.rad 285 B compound.assign.rad 1.1 KiB cond.assign.rad 723 B cond.expr.aggregate.rad 1.1 KiB cond.expr.rad 1.8 KiB cond.for.else.break.rad 326 B cond.for.indexed.rad 238 B cond.for.rad 165 B cond.for.range.indexed.rad 526 B cond.for.range.rad 171 B cond.for.unsigned.range.rad 644 B cond.forever.break.continue.rad 182 B cond.forever.break.rad 232 B cond.fused.rad 926 B cond.if.case.rad 2.2 KiB cond.if.else.min.rad 143 B cond.if.else.rad 225 B cond.if.elseif.rad 420 B cond.if.noelse.rad 120 B cond.if.rad 865 B cond.match.fallthrough.rad 369 B cond.match.guard.rad 1.4 KiB cond.match.guard.regalloc.rad 1.3 KiB cond.while.else.break.rad 282 B cond.while.rad 119 B const.array.copy.mutate.rad 386 B const.array.rad 195 B const.basic.rad 325 B const.char.rad 159 B const.fn.array.rad 664 B const.record.array.rad 1.2 KiB const.record.array.simple.rad 523 B const.record.ctor.rad 170 B const.record.fn.rad 353 B const.record.rad 182 B const.slice.param.rad 333 B const.union.payload.ctor.rad 349 B const.union.record.literal.rad 359 B data.array.rad 767 B data.bool.rad 216 B data.i16.rad 261 B data.i32.rad 281 B data.i8.rad 248 B data.record.rad 561 B data.simple.rad 436 B data.u16.rad 220 B data.u32.rad 240 B data.u8.rad 208 B data.union.rad 886 B debug.tag.rad 557 B edge.cases.2.rad 337 B edge.cases.3.rad 594 B edge.cases.4.rad 1.2 KiB edge.cases.5.rad 1.0 KiB edge.cases.6.rad 2.6 KiB edge.cases.7.addr.bug.rad 224 B edge.cases.8.bug.rad 508 B edge.cases.rad 223 B error.basic.rad 159 B error.catch.rad 1.6 KiB error.division.zero.rad 164 B error.modulo.zero.rad 162 B error.multi.basic.rad 672 B error.multi.catch.rad 772 B error.multi.catch.typed.binding.rad 791 B error.multi.catch.typed.catchall.rad 1.0 KiB error.multi.catch.typed.rad 1.1 KiB error.multi.propagate.multi.rad 953 B error.multi.propagate.rad 825 B error.multi.try.optional.rad 507 B error.slice.bounds.rad 219 B error.try.bang.success.rad 370 B error.try.catch.binding.rad 2.0 KiB error.try.optional.rad 1.8 KiB error.try.rad 4.0 KiB fn.block.scope.rad 508 B fn.callback.nested.rad 1.2 KiB fn.default.rad 131 B fn.local.rad 140 B fn.recursion.2.rad 239 B fn.void.rad 150 B for.else.continue.rad 1.1 KiB frame.large.rad 567 B if-let-mut.rad 1.1 KiB iflet.shadow.leak.rad 317 B integer.bitwise.basic.rad 693 B integer.overflow.rad 1.8 KiB large.blit.store.rad 2.1 KiB let.guard.rad 1.9 KiB literal.w64.rad 1.7 KiB loc.addr.offset.bug.rad 410 B loc.addr.opt.to.opt.rad 433 B loc.addr.optional.assign.rad 408 B loc.addr.record.assign.rad 443 B loop.complex.flow.rad 1007 B loop.sealblock.rad 911 B match.array.rad 3.4 KiB match.char.rad 1.6 KiB match.multi.seal.rad 987 B match.multi.survive.rad 1.6 KiB match.mutref.push.rad 1.0 KiB match.mutref.union.rad 662 B match.nested.call.rad 1.7 KiB match.nested.deep.rad 2.2 KiB match.nested.deref.rad 3.7 KiB match.nested.guard.rad 1.6 KiB match.nested.iflet.guard.rad 1.6 KiB match.nested.iflet.rad 1.4 KiB match.nested.letelse.rad 813 B match.nested.letelse.union.rad 1.3 KiB match.nested.literal.rad 3.1 KiB match.nested.multi.rad 2.4 KiB match.nested.pattern.rad 5.2 KiB match.nested.record.rad 2.0 KiB match.nested.union.rad 2.3 KiB match.nested.whilelet.rad 2.4 KiB match.string.rad 1.8 KiB match.value.copy.rad 2.0 KiB match.void.then.or.rad 1.6 KiB memzero.result.bug.rad 806 B memzero.union.bug.rad 576 B mutref.loop.bug.rad 1.8 KiB opt.assignment.bug.rad 1.3 KiB opt.bug.test.rad 1.4 KiB opt.if.let.complex.rad 6.2 KiB opt.if.let.guard.rad 809 B opt.if.let.rad 956 B opt.nil.check.rad 1.5 KiB opt.record.eq.rad 842 B opt.record.rad 655 B opt.return.array.rad 289 B opt.return.nested.rad 797 B opt.return.record.rad 344 B opt.slice.npo.rad 2.8 KiB opt.type.rad 200 B opt.while.let.complex.rad 404 B panic.rad 111 B placeholder.basic.rad 133 B placeholder.comprehensive.rad 562 B pointer.copy.edge.case.rad 1.3 KiB pointer.slice.index.rad 269 B pointer.slice.store.rad 881 B prog.ackermann.rad 5.0 KiB prog.bignum.rad 9.4 KiB prog.binsearch.rad 2.4 KiB prog.bubblesort.rad 2.0 KiB prog.cordic.rad 6.9 KiB prog.crc32.rad 2.7 KiB prog.dijkstra.rad 7.7 KiB prog.eval.rad 6.2 KiB prog.hanoi.rad 3.8 KiB prog.huffman.rad 9.3 KiB prog.hybridsort.rad 3.0 KiB prog.linkedlist.rad 5.8 KiB prog.lzw.rad 6.7 KiB prog.matmul.rad 2.9 KiB prog.mersenne.rad 5.2 KiB prog.nqueens.rad 3.4 KiB prog.rbtree.rad 8.2 KiB prog.regex.rad 10.2 KiB prog.sha256.rad 7.0 KiB prog.sieve.rad 2.8 KiB prog.symtab.rad 10.1 KiB prog.tokenizer.rad 13.8 KiB prog.vm.rad 17.4 KiB ptr.assign.rad 137 B ptr.deref.rad 622 B ptr.eq.rad 966 B ptr.mutate.rad 244 B ptr.opaque.rad 1.4 KiB record.access.rad 285 B record.alignment.rad 179 B record.array.elements.rad 1.7 KiB record.copy.rad 2.0 KiB record.field.assign.rad 184 B record.nested.calls.2.rad 612 B record.nested.calls.3.rad 734 B record.param.lit.rad 353 B record.ptr.access.rad 227 B record.ptr.mutate.rad 243 B record.shorthand.rad 1.5 KiB record.unlabeled.rad 407 B ref.if.bug.rad 519 B ref.immut.loop.bug.rad 670 B ref.mut.ptr.rad 261 B regalloc.callee.save.rad 1.5 KiB regalloc.spill.reuse.rad 473 B reserve.loop.rad 392 B result.void.success.rad 716 B slice.alloc.loop.rad 788 B slice.append.rad 3.3 KiB slice.cap.rad 941 B slice.delete.rad 971 B slice.of.rad 460 B slice.subslice.rad 1.4 KiB spill.blockarg.clobber.rad 3.5 KiB spill.loop.rad 1.6 KiB stack.local.corrupt.rad 320 B static.array.mutate.rad 387 B static.basic.rad 327 B static.fn.array.rad 628 B static.record.array.rad 503 B static.slice.index.assign.rad 408 B static.slice.offset.rad 668 B string.basic.rad 149 B string.escape.rad 349 B string.index.rad 116 B switch.blockargs.clobber.rad 1.3 KiB trait.aggregate.ret.rad 1.5 KiB trait.array.optional.rad 1.7 KiB trait.basic.rad 565 B trait.control.flow.rad 1.1 KiB trait.fn.param.rad 1.6 KiB trait.multiple.methods.rad 1.2 KiB trait.multiple.traits.rad 1.2 KiB trait.multiple.types.rad 1.3 KiB trait.supertrait.rad 2.5 KiB trait.throws.rad 1.0 KiB trait.writer.rad 2.6 KiB type.unify.rad 4.5 KiB undefined.rad 417 B union-tag.rad 911 B union.bitfield.rad 1.2 KiB union.discriminant.cast.rad 389 B union.edge.case.2.rad 679 B union.edge.case.3.rad 608 B union.mixed.assign.rad 977 B union.payload.mutref.rad 1.4 KiB union.payload.rad 580 B union.record.forward.rad 1.3 KiB union.void.match.rad 403 B union.void.rad 824 B unsigned.compare.rad 1.9 KiB var.align.rad 1013 B var.infer.rad 549 B decode.rad 14.6 KiB emit.rad 24.4 KiB encode.rad 19.9 KiB isel.rad 41.1 KiB printer.rad 13.0 KiB tests.rad 15.7 KiB rv64.rad 13.0 KiB collections/ lang/ sys/ arch.rad 65 B collections.rad 36 B fmt.rad 3.8 KiB intrinsics.rad 206 B io.rad 1.2 KiB lang.rad 222 B mem.rad 2.2 KiB sys.rad 167 B testing.rad 2.4 KiB tests.rad 11.6 KiB vec.rad 3.1 KiB std.rad 231 B scripts/ seed/ test/ vim/ .gitignore 353 B .gitsigners 112 B LICENSE 1.1 KiB Makefile 3.1 KiB README 2.5 KiB std.lib 987 B std.lib.test 252 B
lib/std/arch/rv64/tests/prog.lzw.rad 6.7 KiB raw
1
//! LZW compression and decompression.
2
//! Implement the Lempel-Ziv-Welch algorithm with a fixed-size dictionary.
3
//! Encode a byte buffer, decode it, and verify perfect round-trip.
4
5
const MAX_DICT: u32 = 512;
6
const INIT_DICT: u32 = 258;
7
const CLEAR_CODE: u32 = 256;
8
const EOI_CODE: u32 = 257;
9
10
record DictEntry {
11
    prefix: u32,
12
    suffix: u8,
13
}
14
15
record LzwState {
16
    encDict: *mut [DictEntry],
17
    encDictSize: u32,
18
    decDict: *mut [DictEntry],
19
    decDictSize: u32,
20
    encoded: *mut [u32],
21
    encLen: u32,
22
    decoded: *mut [u8],
23
    decLen: u32,
24
    temp: *mut [u8],
25
}
26
27
fn initEncDict(s: *mut LzwState) {
28
    s.encDictSize = INIT_DICT;
29
    let mut i: u32 = 0;
30
    while i < 256 {
31
        s.encDict[i] = DictEntry { prefix: 0xFFFF, suffix: i as u8 };
32
        i += 1;
33
    }
34
}
35
36
fn initDecDict(s: *mut LzwState) {
37
    s.decDictSize = INIT_DICT;
38
    let mut i: u32 = 0;
39
    while i < 256 {
40
        s.decDict[i] = DictEntry { prefix: 0xFFFF, suffix: i as u8 };
41
        i += 1;
42
    }
43
}
44
45
fn dictLookup(s: *LzwState, prefix: u32, suffix: u8) -> u32 {
46
    let mut i: u32 = 0;
47
    while i < s.encDictSize {
48
        if s.encDict[i].prefix == prefix and s.encDict[i].suffix == suffix {
49
            return i;
50
        }
51
        i += 1;
52
    }
53
    return 0xFFFFFFFF;
54
}
55
56
fn dictAdd(s: *mut LzwState, prefix: u32, suffix: u8) {
57
    if s.encDictSize < MAX_DICT {
58
        s.encDict[s.encDictSize] = DictEntry { prefix, suffix };
59
        s.encDictSize += 1;
60
    }
61
}
62
63
fn emitCode(s: *mut LzwState, code: u32) {
64
    s.encoded[s.encLen] = code;
65
    s.encLen += 1;
66
}
67
68
fn encode(s: *mut LzwState, data: *[u8]) {
69
    initEncDict(s);
70
    s.encLen = 0;
71
72
    if data.len == 0 {
73
        emitCode(s, EOI_CODE);
74
        return;
75
    }
76
77
    let mut w: u32 = data[0] as u32;
78
    let mut i: u32 = 1;
79
80
    while i < data.len {
81
        let c: u8 = data[i];
82
        let wc: u32 = dictLookup(s, w, c);
83
        if wc != 0xFFFFFFFF {
84
            w = wc;
85
        } else {
86
            emitCode(s, w);
87
            dictAdd(s, w, c);
88
            w = c as u32;
89
        }
90
        i += 1;
91
    }
92
    emitCode(s, w);
93
    emitCode(s, EOI_CODE);
94
}
95
96
fn decodeString(s: *mut LzwState, code: u32) -> u32 {
97
    let mut len: u32 = 0;
98
    let mut c: u32 = code;
99
    while c != 0xFFFF and c < s.decDictSize {
100
        s.temp[len] = s.decDict[c].suffix;
101
        len += 1;
102
        c = s.decDict[c].prefix;
103
    }
104
    let mut a: u32 = 0;
105
    let mut b: u32 = len - 1;
106
    while a < b {
107
        let tmp: u8 = s.temp[a];
108
        s.temp[a] = s.temp[b];
109
        s.temp[b] = tmp;
110
        a += 1;
111
        b -= 1;
112
    }
113
    return len;
114
}
115
116
fn firstByte(s: *LzwState, code: u32) -> u8 {
117
    let mut c: u32 = code;
118
    while s.decDict[c].prefix != 0xFFFF and s.decDict[c].prefix < s.decDictSize {
119
        c = s.decDict[c].prefix;
120
    }
121
    return s.decDict[c].suffix;
122
}
123
124
fn decDictAdd(s: *mut LzwState, prefix: u32, suffix: u8) {
125
    if s.decDictSize < MAX_DICT {
126
        s.decDict[s.decDictSize] = DictEntry { prefix, suffix };
127
        s.decDictSize += 1;
128
    }
129
}
130
131
fn outputByte(s: *mut LzwState, b: u8) {
132
    s.decoded[s.decLen] = b;
133
    s.decLen += 1;
134
}
135
136
fn decode(s: *mut LzwState) {
137
    initDecDict(s);
138
    s.decLen = 0;
139
140
    if s.encLen == 0 {
141
        return;
142
    }
143
144
    let mut pos: u32 = 0;
145
    let mut code: u32 = s.encoded[pos];
146
    pos += 1;
147
148
    if code == EOI_CODE {
149
        return;
150
    }
151
152
    outputByte(s, code as u8);
153
    let mut prevCode: u32 = code;
154
155
    while pos < s.encLen {
156
        code = s.encoded[pos];
157
        pos += 1;
158
159
        if code == EOI_CODE {
160
            return;
161
        }
162
163
        if code < s.decDictSize {
164
            let len: u32 = decodeString(s, code);
165
            let mut i: u32 = 0;
166
            while i < len {
167
                outputByte(s, s.temp[i]);
168
                i += 1;
169
            }
170
            decDictAdd(s, prevCode, s.temp[0]);
171
        } else {
172
            let fb: u8 = firstByte(s, prevCode);
173
            let len: u32 = decodeString(s, prevCode);
174
            let mut i: u32 = 0;
175
            while i < len {
176
                outputByte(s, s.temp[i]);
177
                i += 1;
178
            }
179
            outputByte(s, fb);
180
            decDictAdd(s, prevCode, fb);
181
        }
182
        prevCode = code;
183
    }
184
}
185
186
fn testSimple(s: *mut LzwState) -> i32 {
187
    let data: *[u8] = "ABABABABAB";
188
    encode(s, data);
189
190
    assert s.encoded[s.encLen - 1] == EOI_CODE;
191
192
    decode(s);
193
    assert s.decLen == 10;
194
    let mut i: u32 = 0;
195
    while i < 10 {
196
        assert s.decoded[i] == data[i];
197
        i += 1;
198
    }
199
    return 0;
200
}
201
202
fn testDistinct(s: *mut LzwState) -> i32 {
203
    let data: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
204
    encode(s, &data[..]);
205
206
    decode(s);
207
    assert s.decLen == 16;
208
    let mut i: u32 = 0;
209
    while i < 16 {
210
        assert s.decoded[i] == data[i];
211
        i += 1;
212
    }
213
    return 0;
214
}
215
216
fn testRepetitive(s: *mut LzwState) -> i32 {
217
    let mut data: [u8; 64] = [65; 64];
218
    encode(s, &data[..]);
219
220
    assert s.encLen < 32;
221
222
    decode(s);
223
    assert s.decLen == 64;
224
    let mut i: u32 = 0;
225
    while i < 64 {
226
        assert s.decoded[i] == 65;
227
        i += 1;
228
    }
229
    return 0;
230
}
231
232
fn testMixed(s: *mut LzwState) -> i32 {
233
    let data: *[u8] = "TOBEORNOTTOBEORTOBEORNOT";
234
    encode(s, data);
235
236
    decode(s);
237
    assert s.decLen == 24;
238
    let mut i: u32 = 0;
239
    while i < 24 {
240
        assert s.decoded[i] == data[i];
241
        i += 1;
242
    }
243
244
    assert s.encLen - 1 < 24;
245
246
    return 0;
247
}
248
249
fn testEmpty(s: *mut LzwState) -> i32 {
250
    encode(s, &[]);
251
    assert s.encLen == 1;
252
    assert s.encoded[0] == EOI_CODE;
253
254
    decode(s);
255
    assert s.decLen == 0;
256
    return 0;
257
}
258
259
fn testSingle(s: *mut LzwState) -> i32 {
260
    let data: *[u8] = "*";
261
    encode(s, data);
262
263
    decode(s);
264
    assert s.decLen == 1;
265
    assert s.decoded[0] == 42;
266
    return 0;
267
}
268
269
@default fn main() -> i32 {
270
    let mut encDict: [DictEntry; 512] = [DictEntry { prefix: 0xFFFF, suffix: 0 }; 512];
271
    let mut decDict: [DictEntry; 512] = [DictEntry { prefix: 0xFFFF, suffix: 0 }; 512];
272
    let mut encoded: [u32; 512] = [0; 512];
273
    let mut decoded: [u8; 256] = [0; 256];
274
    let mut temp: [u8; 256] = [0; 256];
275
276
    let mut s: LzwState = LzwState {
277
        encDict: &mut encDict[..],
278
        encDictSize: 0,
279
        decDict: &mut decDict[..],
280
        decDictSize: 0,
281
        encoded: &mut encoded[..],
282
        encLen: 0,
283
        decoded: &mut decoded[..],
284
        decLen: 0,
285
        temp: &mut temp[..],
286
    };
287
288
    let r1: i32 = testSimple(&mut s);
289
    if r1 != 0 { return 10 + r1; }
290
291
    let r2: i32 = testDistinct(&mut s);
292
    if r2 != 0 { return 20 + r2; }
293
294
    let r3: i32 = testRepetitive(&mut s);
295
    if r3 != 0 { return 30 + r3; }
296
297
    let r4: i32 = testMixed(&mut s);
298
    if r4 != 0 { return 40 + r4; }
299
300
    let r5: i32 = testEmpty(&mut s);
301
    if r5 != 0 { return 50 + r5; }
302
303
    let r6: i32 = testSingle(&mut s);
304
    if r6 != 0 { return 60 + r6; }
305
306
    return 0;
307
}