compiler/ lib/ scripts/ seed/ test/ tests/ abi.sizes.rad 3.4 KiB addfn.rad 52 B addfn.ril 76 B aggregate.return.rad 4.1 KiB arith.assignment.rad 595 B arith.basic.rad 191 B arith.modulo.rad 111 B arith.subword.rad 3.9 KiB arith.subword.ril 4.3 KiB arith.sum.rad 192 B arith.w64.rad 4.1 KiB arith.w64.ril 5.2 KiB array.aggregate.stride.rad 753 B array.aggregate.stride.ril 1.1 KiB array.assign.rad 221 B array.assign.ril 526 B array.bounds.check.rad 321 B array.index.assign.rad 382 B array.index.rad 264 B array.index.ril 496 B array.len.const.rad 348 B array.len.const.ril 200 B array.length.rad 277 B array.literal.rad 136 B array.literal.ril 329 B array.math.rad 1.2 KiB array.nested.assign.rad 319 B array.nested.rad 325 B array.nested.ril 922 B array.record.elements.rad 1.7 KiB array.repeat.edge.rad 548 B array.repeat.rad 828 B array.repeat.ril 3.0 KiB array.return.rad 345 B array.slice.empty.rad 123 B array.slice.full.rad 110 B array.slice.full.ril 168 B array.slice.gen.end.rad 141 B array.slice.gen.index.rad 154 B array.slice.gen.open.rad 140 B array.slice.gen.start.end.rad 142 B array.slice.gen.start.rad 141 B array.slice.openend.rad 134 B array.slice.openend.ril 245 B array.slice.openstart.rad 134 B array.slice.openstart.ril 183 B array.slice.rad 774 B as.precedence.rad 226 B assert.basic.rad 402 B assert.basic.ril 624 B assert.fail.rad 138 B assert.false.rad 140 B assert.message.rad 123 B assert.message.ril 141 B assert.true.rad 115 B assign.loop.rad 205 B assign.loop.ril 242 B assign.multi.var.rad 182 B assign.multi.var.ril 73 B assign.mutable.rad 6.1 KiB assign.param.rad 142 B assign.param.ril 96 B assign.rad 144 B assign.self.ref.rad 153 B assign.self.ref.ril 92 B assign.sequential.rad 155 B assign.sequential.ril 52 B assign.shadow.mutable.rad 461 B assign.use.intermediate.rad 187 B assign.use.intermediate.ril 99 B average.rad 185 B average.ril 378 B binop.arith.rad 479 B binop.arith.ril 389 B binop.bitwise.rad 1.2 KiB binop.bitwise.ril 1.2 KiB binop.cmp.rad 441 B binop.logical.rad 216 B binop.logical.ril 373 B binop.shift.rad 197 B binop.shift.ril 149 B binop.unsigned.rad 317 B binop.unsigned.ril 236 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 705 B bool.comparison.union.gen.rad 1.2 KiB bool.comparison.union.record.gen.rad 1.5 KiB bool.comparison.union.simple.gen.rad 296 B bool.operators.complex.rad 384 B bool.operators.rad 831 B bool.short.circuit.rad 2.3 KiB bool.simple.rad 209 B bool.values.rad 787 B builtin.alignof.rad 692 B builtin.alignof.ril 287 B builtin.size.align.rad 1.2 KiB builtin.sizeof.rad 650 B builtin.sizeof.ril 282 B builtin.sliceof.mut.rad 621 B builtin.sliceof.rad 505 B byte.load.store.rad 372 B byte.load.store.ril 730 B call.arg.clobber.rad 732 B call.basic.rad 256 B call.clobber.rad 477 B call.tests.rad 764 B call.tests.ril 603 B cast.basic.rad 848 B cast.basic.ril 594 B cast.narrow.rad 583 B cast.narrow.ril 557 B cast.same.size.rad 1.0 KiB cast.same.size.ril 1.1 KiB casting.numbers.rad 1.5 KiB char.literal.rad 180 B cmp.rel.rad 733 B cmp.rel.ril 467 B cmp.unsigned.rad 733 B cmp.unsigned.ril 467 B coercion.implicit.rad 917 B coercion.implicit.ril 1.0 KiB compound.assign.field.rad 300 B compound.assign.rad 1.1 KiB compound.assign.ril 2.0 KiB cond.assign.merge.basic.rad 213 B cond.assign.merge.basic.ril 172 B cond.assign.merge.rad 206 B cond.assign.merge.ril 169 B cond.assign.rad 738 B cond.elseif.rad 204 B cond.elseif.ril 181 B cond.expr.aggregate.rad 1.2 KiB cond.expr.rad 1.9 KiB cond.expr.ril 3.5 KiB cond.for.else.break.rad 341 B cond.for.indexed.rad 253 B cond.for.rad 180 B cond.for.range.indexed.rad 541 B cond.for.range.rad 186 B cond.for.unsigned.range.rad 659 B cond.forever.break.continue.rad 197 B cond.forever.break.rad 247 B cond.fused.rad 941 B cond.if.case.rad 2.2 KiB cond.if.else.min.rad 158 B cond.if.else.rad 240 B cond.if.elseif.rad 435 B cond.if.noelse.rad 135 B cond.if.rad 880 B cond.ifelse.rad 104 B cond.ifelse.ril 117 B cond.iflet.case.rad 170 B cond.iflet.case.ril 114 B cond.iflet.guard.rad 182 B cond.iflet.guard.ril 165 B cond.iflet.mut.rad 191 B cond.iflet.mut.ril 217 B cond.iflet.noelse.rad 156 B cond.iflet.noelse.ril 225 B cond.iflet.optional.rad 184 B cond.iflet.optional.ril 118 B cond.iflet.optional.value.rad 194 B cond.iflet.optional.value.ril 206 B cond.letelse.case.rad 146 B cond.letelse.case.ril 118 B cond.letelse.guard.rad 160 B cond.letelse.guard.ril 169 B cond.letelse.mut.rad 181 B cond.letelse.mut.ril 221 B cond.letelse.optional.rad 160 B cond.letelse.optional.ril 122 B cond.match.fallthrough.rad 384 B cond.match.guard.rad 1.4 KiB cond.match.guard.regalloc.rad 1.3 KiB cond.nested.rad 138 B cond.nested.ril 185 B cond.simple.rad 86 B cond.simple.ril 118 B cond.while.else.break.rad 297 B cond.while.rad 134 B const-expr-array-size.rad 356 B const-expr-cast.rad 1.0 KiB const-expr-literal.rad 628 B const-expr-refs.rad 716 B const.array.copy.mutate.rad 386 B const.array.ident.rad 238 B const.array.ident.ril 146 B const.array.rad 210 B const.array.record.ident.rad 378 B const.array.record.ident.ril 353 B const.array.repeat.record.rad 216 B const.array.repeat.record.ril 399 B const.array.ril 392 B const.array.strings.slice.rad 271 B const.array.strings.slice.ril 539 B const.basic.rad 340 B const.char.rad 174 B const.fn.array.rad 664 B const.negative.rad 322 B const.negative.ril 338 B const.record.array.rad 1.2 KiB const.record.array.simple.rad 538 B const.record.ctor.rad 185 B const.record.ctor.ril 415 B const.record.fn.rad 353 B const.record.mutcopy.rad 450 B const.record.mutcopy.ril 385 B const.record.nested.rad 393 B const.record.nested.ril 474 B const.record.packed.rad 266 B const.record.packed.ril 284 B const.record.padded.rad 266 B const.record.padded.ril 318 B const.record.rad 197 B const.record.ril 221 B const.record.union.rad 593 B const.record.union.ril 625 B const.scalar.rad 102 B const.scalar.ril 82 B const.slice.of.slices.rad 232 B const.slice.of.slices.ril 876 B const.slice.param.rad 333 B const.string.rad 111 B const.string.ril 285 B const.string.scoped.names.rad 254 B const.string.scoped.names.ril 840 B const.union.payload.ctor.rad 364 B const.union.payload.ctor.ril 507 B const.union.record.literal.rad 374 B const.union.record.literal.ril 506 B data.array.rad 782 B data.bool.rad 231 B data.i16.rad 276 B data.i32.rad 296 B data.i8.rad 263 B data.record.rad 576 B data.simple.rad 451 B data.u16.rad 235 B data.u32.rad 255 B data.u8.rad 223 B data.union.rad 901 B debug.tag.rad 557 B ecall.i64.rad 497 B edge.cases.2.rad 352 B edge.cases.3.rad 594 B edge.cases.4.rad 1.2 KiB edge.cases.5.rad 1.1 KiB edge.cases.6.rad 2.6 KiB edge.cases.7.addr.bug.rad 224 B edge.cases.8.bug.rad 523 B edge.cases.rad 238 B error.basic.rad 174 B error.catch.rad 1.6 KiB error.catch.return.rad 403 B error.catch.return.ril 634 B error.division.zero.rad 164 B error.modulo.zero.rad 162 B error.multi.basic.rad 687 B error.multi.catch.rad 787 B error.multi.catch.typed.binding.rad 806 B error.multi.catch.typed.catchall.rad 1.0 KiB error.multi.catch.typed.rad 1.1 KiB error.multi.propagate.multi.rad 968 B error.multi.propagate.rad 840 B error.multi.try.optional.rad 522 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.9 KiB error.try.rad 4.0 KiB externfn.rad 39 B externfn.ril 37 B fibonacci.rad 122 B fibonacci.ril 247 B field.aggregate.rad 793 B field.aggregate.ril 782 B fn.block.scope.rad 508 B fn.callback.nested.rad 1.2 KiB fn.default.rad 146 B fn.local.rad 155 B fn.ptr.assign.rad 277 B fn.ptr.assign.ril 143 B fn.ptr.call.rad 258 B fn.ptr.call.ril 183 B fn.ptr.param.rad 356 B fn.ptr.param.ril 282 B fn.recursion.2.rad 239 B fn.void.rad 165 B for.else.continue.rad 1.1 KiB frame.large.rad 582 B if-let-mut.rad 1.2 KiB iflet.shadow.leak.rad 317 B index.u8.rad 594 B int.default.i64.rad 1.1 KiB integer.bitwise.basic.rad 708 B integer.overflow.rad 1.8 KiB intrinsic.ebreak.rad 97 B intrinsic.ebreak.ril 76 B intrinsic.ecall.rad 175 B intrinsic.ecall.ril 131 B large.blit.store.rad 2.1 KiB let.copy.semantics.rad 871 B let.copy.semantics.ril 879 B let.guard.rad 1.9 KiB let.placeholder.rad 291 B let.placeholder.ril 220 B literal.char.rad 209 B literal.char.ril 127 B literal.slice.bytes.rad 124 B literal.slice.bytes.ril 245 B literal.slice.dedup.rad 199 B literal.slice.dedup.ril 407 B literal.slice.empty.rad 100 B literal.slice.empty.ril 157 B literal.slice.multi.rad 170 B literal.slice.multi.ril 460 B literal.slice.rad 123 B literal.slice.record.rad 211 B literal.slice.record.ril 676 B literal.slice.ril 254 B literal.string.dedup.rad 179 B literal.string.dedup.ril 395 B literal.string.empty.rad 93 B literal.string.empty.ril 230 B literal.string.fns.rad 180 B literal.string.fns.ril 434 B literal.string.multi.rad 153 B literal.string.multi.ril 444 B literal.string.rad 108 B literal.string.ril 229 B literal.w64.rad 1.7 KiB load.u32.high.rad 1.8 KiB loc.addr.offset.bug.rad 425 B loc.addr.opt.to.opt.rad 448 B loc.addr.optional.assign.rad 423 B loc.addr.record.assign.rad 458 B local.multi.rad 85 B local.multi.ril 67 B local.mut.rad 75 B local.mut.ril 45 B local.simple.rad 60 B local.simple.ril 45 B loop.break.rad 152 B loop.break.ril 228 B loop.complex.flow.rad 1022 B loop.continue.rad 211 B loop.continue.ril 327 B loop.for.array.rad 219 B loop.for.array.ril 315 B loop.for.break.bound.rad 161 B loop.for.break.bound.ril 264 B loop.for.continue.rad 395 B loop.for.continue.ril 741 B loop.for.indexed.rad 145 B loop.for.indexed.ril 285 B loop.for.placeholder.rad 313 B loop.for.placeholder.ril 457 B loop.for.rad 116 B loop.for.ril 220 B loop.for.slice.rad 212 B loop.for.slice.ril 362 B loop.for.unsigned.range.rad 309 B loop.for.unsigned.range.ril 481 B loop.infinite.rad 41 B loop.infinite.ril 78 B loop.mutable.rad 371 B loop.mutable.ril 617 B loop.nested.break.rad 380 B loop.nested.break.ril 461 B loop.nested.continue.rad 406 B loop.nested.continue.ril 581 B loop.return.rad 137 B loop.return.ril 179 B loop.sealblock.rad 926 B loop.while.false.noparams.rad 175 B loop.while.false.noparams.ril 171 B loop.while.nested.shortcircuit.rad 860 B loop.while.nested.shortcircuit.ril 589 B loop.while.rad 156 B loop.while.ril 241 B loop.whilelet.case.rad 251 B loop.whilelet.case.ril 204 B loop.whilelet.guard.rad 257 B loop.whilelet.guard.ril 256 B loop.whilelet.optional.rad 208 B loop.whilelet.optional.ril 217 B loop.whilelet.union.rad 368 B loop.whilelet.union.ril 382 B match.array.rad 3.5 KiB match.char.rad 1.6 KiB match.more.rad 643 B match.more.ril 683 B match.multi.seal.rad 1002 B match.multi.seal.ril 924 B match.multi.survive.rad 1.6 KiB match.mutref.push.rad 1.0 KiB match.mutref.union.rad 677 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.iflet.ril 2.3 KiB match.nested.letelse.rad 828 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.pattern.ril 8.3 KiB match.nested.record.rad 2.1 KiB match.nested.record.ril 3.5 KiB match.nested.union.rad 2.3 KiB match.nested.union.ril 4.5 KiB match.nested.whilelet.rad 2.4 KiB match.optional.aggregate.rad 222 B match.optional.aggregate.ril 578 B match.optional.rad 183 B match.optional.ril 164 B match.record.pattern.rad 325 B match.record.pattern.ril 287 B match.simple.rad 367 B match.simple.ril 347 B match.string.rad 1.8 KiB match.switch.rad 217 B match.switch.ril 187 B match.value.copy.rad 2.0 KiB match.void.then.or.rad 1.6 KiB memzero.result.bug.rad 821 B memzero.union.bug.rad 591 B method.basic.rad 554 B method.chain.rad 560 B method.multiple.rad 888 B method.ptr.rad 662 B method.pub.rad 238 B method.return.rad 599 B method.throws.rad 829 B method.union.rad 424 B method.with.trait.rad 644 B mixedtypes.rad 79 B mixedtypes.ril 82 B multi.throw.basic.rad 272 B multi.throw.basic.ril 526 B multi.throw.catch.typed.rad 436 B multi.throw.catch.typed.ril 1015 B multi.throw.propagate.rad 335 B multi.throw.propagate.ril 873 B multiplefns.rad 110 B multiplefns.ril 146 B mutref.loop.bug.rad 1.8 KiB mutref.loop.rad 281 B mutref.loop.ril 368 B mutref.scalar.rad 228 B mutref.scalar.ril 324 B nil.cmp.rad 622 B nil.cmp.ril 423 B noparams.rad 38 B noparams.ril 43 B opt.array.hint.rad 951 B 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.ptr.return.nil.rad 85 B opt.ptr.return.nil.ril 51 B opt.record.eq.rad 842 B opt.record.eq.rev.rad 307 B opt.record.eq.rev.ril 635 B opt.record.eq.ril 3.4 KiB opt.record.rad 655 B opt.return.array.rad 289 B opt.return.nested.rad 797 B opt.return.nil.rad 82 B opt.return.nil.ril 114 B opt.return.record.rad 344 B opt.return.value.rad 91 B opt.return.value.ril 138 B opt.slice.npo.rad 2.8 KiB opt.slice.npo.ril 6.8 KiB opt.type.rad 215 B opt.while.let.complex.rad 404 B optional.aggregate.eq.rad 286 B optional.aggregate.eq.ril 695 B optional.eq.rad 131 B optional.eq.ril 253 B optional.ptr.eq.rad 313 B optional.ptr.eq.ril 309 B panic.basic.rad 70 B panic.basic.ril 46 B panic.rad 111 B placeholder.basic.rad 148 B placeholder.comprehensive.rad 577 B pointer.copy.edge.case.rad 1.3 KiB pointer.slice.index.rad 284 B pointer.slice.store.rad 896 B pointerfn.rad 50 B pointerfn.ril 54 B prog.ackermann.rad 5.0 KiB prog.bignum.rad 9.5 KiB prog.binsearch.rad 2.5 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.1 KiB prog.linkedlist.rad 5.9 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.3 KiB prog.regex.rad 10.2 KiB prog.sha256.rad 7.1 KiB prog.sieve.rad 2.8 KiB prog.symtab.rad 10.1 KiB prog.tokenizer.rad 13.9 KiB prog.vm.rad 17.4 KiB ptr.addressof.field.rad 132 B ptr.addressof.field.ril 78 B ptr.addressof.local.rad 455 B ptr.addressof.local.ril 280 B ptr.addressof.rad 119 B ptr.addressof.ril 213 B ptr.assign.rad 137 B ptr.assign.ril 130 B ptr.deref.rad 622 B ptr.deref.record.rad 282 B ptr.deref.record.ril 190 B ptr.deref.ril 1.1 KiB ptr.eq.rad 981 B ptr.mutate.rad 244 B ptr.opaque.rad 1.4 KiB ptr.subscript.assign.rad 129 B ptr.subscript.assign.ril 288 B range.arithmetic.rad 723 B record.access.rad 300 B record.alignment.rad 194 B record.array.elements.rad 1.7 KiB record.assign.blit.rad 111 B record.assign.blit.ril 158 B record.copy.rad 2.0 KiB record.ctor.tuple.rad 69 B record.ctor.tuple.ril 127 B record.empty.eq.rad 272 B record.empty.eq.ril 226 B record.eq.rad 223 B record.eq.ril 214 B record.field.assign.rad 199 B record.field.assign.ril 308 B record.literal.labeled.rad 103 B record.literal.labeled.ril 127 B record.mixed.layout.rad 116 B record.mixed.layout.ril 149 B record.nested.calls.2.rad 612 B record.nested.calls.3.rad 749 B record.nested.eq.rad 246 B record.nested.eq.ril 522 B record.nested.lit.rad 170 B record.nested.lit.ril 188 B record.param.lit.rad 368 B record.ptr.access.rad 242 B record.ptr.access.ril 198 B record.ptr.mutate.rad 235 B record.shorthand.rad 1.5 KiB record.unlabeled.deref.rad 1.4 KiB record.unlabeled.rad 407 B ref.if.bug.rad 519 B ref.immut.loop.bug.rad 670 B ref.mut.ptr.rad 253 B regalloc.callee.save.rad 1.5 KiB regalloc.spill.reuse.rad 488 B reserve.loop.rad 407 B reserve.loop.ril 473 B result.void.success.rad 701 B return.lit.rad 45 B return.lit.ril 50 B return.param.rad 48 B return.param.ril 54 B simplefn.rad 45 B simplefn.ril 51 B slice.alloc.loop.rad 803 B slice.append.rad 4.1 KiB slice.append.ril 18.4 KiB slice.assign.mismatch.rad 216 B slice.assign.rad 1.4 KiB slice.basic.rad 742 B slice.basic.ril 711 B slice.cap.rad 956 B slice.delete.rad 986 B slice.delete.ril 4.8 KiB slice.eq.rad 126 B slice.eq.ril 209 B slice.index.rad 104 B slice.index.ril 278 B slice.mutable.rad 281 B slice.mutable.ril 1.7 KiB slice.of.rad 475 B slice.range.rad 606 B slice.range.ril 1.2 KiB slice.runtime.i32.rad 237 B slice.runtime.i32.ril 725 B slice.runtime.literal.rad 240 B slice.runtime.literal.ril 455 B slice.subslice.rad 1.4 KiB spill.blockarg.clobber.rad 3.5 KiB spill.loop.rad 1.6 KiB stack.local.corrupt.rad 335 B static.array.mutate.rad 402 B static.assign.rad 127 B static.assign.ril 244 B static.basic.rad 327 B static.fn.array.rad 628 B static.local.decl.rad 191 B static.local.decl.ril 280 B static.record.array.rad 518 B static.scalar.rad 109 B static.scalar.ril 135 B static.slice.index.assign.rad 408 B static.slice.offset.rad 683 B string.basic.rad 164 B string.escape.rad 364 B string.index.rad 131 B switch.blockargs.clobber.rad 1.4 KiB trait.aggregate.ret.rad 1.5 KiB trait.array.optional.rad 1.7 KiB trait.basic.rad 580 B trait.control.flow.rad 1.2 KiB trait.dispatch.rad 323 B trait.dispatch.ril 469 B trait.fn.param.rad 1.7 KiB trait.multiple.methods.rad 1.2 KiB trait.multiple.traits.rad 1.2 KiB trait.multiple.types.rad 1.3 KiB trait.object.rad 356 B trait.object.ril 496 B trait.supertrait.rad 2.6 KiB trait.supertrait.ril 3.8 KiB trait.throws.rad 1.0 KiB trait.writer.rad 2.6 KiB trivial.phi.rad 1.1 KiB trivial.phi.ril 512 B try.basic.rad 391 B try.basic.ril 879 B try.catch.rad 339 B try.catch.ril 837 B try.optional.rad 363 B try.optional.ril 760 B try.panic.rad 351 B try.panic.ril 639 B type.unify.rad 4.5 KiB undefined.aggregate.rad 152 B undefined.aggregate.ril 84 B undefined.primitive.rad 115 B undefined.primitive.ril 48 B undefined.rad 432 B undefined.record.field.rad 1.6 KiB undefined.record.field.ril 751 B union-tag.rad 926 B union.bitfield.rad 1.2 KiB union.ctor.rad 552 B union.ctor.ril 385 B union.discriminant.cast.rad 389 B union.edge.case.2.rad 694 B union.edge.case.3.rad 623 B union.eq.rad 783 B union.eq.ril 1.4 KiB union.eq.void.ctor.rad 378 B union.eq.void.ctor.ril 131 B union.eq.void.rad 178 B union.eq.void.ril 75 B union.match.bind.rad 259 B union.match.bind.ril 238 B union.match.ref.rad 1.1 KiB union.match.ref.ril 1.2 KiB union.match.tag.rad 858 B union.match.tag.ril 820 B union.mixed.assign.rad 992 B union.payload.mutref.rad 1.4 KiB union.payload.rad 595 B union.payload.record.eq.rad 292 B union.payload.record.eq.ril 984 B union.record.forward.rad 1.3 KiB union.record.literal.rad 444 B union.record.literal.ril 391 B union.variant.access.rad 731 B union.variant.access.ril 506 B union.void.match.rad 418 B union.void.rad 839 B unop.rad 478 B unop.ril 376 B unsigned.compare.rad 1.9 KiB var.align.rad 1.0 KiB var.infer.rad 564 B var.shadow.rad 236 B var.shadow.ril 145 B void.throw.rad 270 B void.throw.ril 707 B voidfn.rad 18 B voidfn.ril 43 B run 1.9 KiB runner.rad 7.0 KiB vim/ .gitignore 353 B .gitsigners 112 B LICENSE 1.1 KiB Makefile 3.0 KiB README 2.5 KiB std.lib 1.0 KiB std.lib.test 252 B
test/tests/prog.vm.rad 17.4 KiB raw
1
//! returns: 0
2
//! Stack-based virtual machine.
3
//! Implement a bytecode interpreter for a simple stack machine with
4
//! arithmetic, comparisons, jumps, local variables, and function calls.
5
//! Exercises: tagged unions, match, throw/try/catch, error handling,
6
//! records with slice fields, and complex interacting state.
7
8
const MAX_STACK: u32 = 64;
9
const MAX_CODE: u32 = 256;
10
const MAX_LOCALS: u32 = 16;
11
const MAX_FRAMES: u32 = 8;
12
13
/// Bytecode instructions.
14
union Op {
15
    /// Push an immediate value.
16
    Push(i32),
17
    /// Pop top two, push sum.
18
    Add,
19
    /// Pop top two, push difference (second - first).
20
    Sub,
21
    /// Pop top two, push product.
22
    Mul,
23
    /// Pop top two, push quotient.
24
    Div,
25
    /// Pop top two, push 1 if equal, 0 otherwise.
26
    Eq,
27
    /// Pop top two, push 1 if second < first, 0 otherwise.
28
    Lt,
29
    /// Pop top two, push 1 if second > first, 0 otherwise.
30
    Gt,
31
    /// Negate top of stack.
32
    Neg,
33
    /// Duplicate top of stack.
34
    Dup,
35
    /// Pop and discard top of stack.
36
    Pop,
37
    /// Store top of stack into local variable.
38
    Store(u32),
39
    /// Load local variable onto stack.
40
    Load(u32),
41
    /// Unconditional jump to instruction index.
42
    Jump(u32),
43
    /// Pop; if zero, jump to instruction index.
44
    JumpIfZero(u32),
45
    /// Call function at instruction index, saving return address.
46
    Call(u32),
47
    /// Return from function call.
48
    Ret,
49
    /// Halt execution, top of stack is result.
50
    Halt,
51
}
52
53
/// A call frame for function calls.
54
record Frame {
55
    returnAddr: u32,
56
    localBase: u32,
57
}
58
59
/// The VM state.
60
record VM {
61
    code: *[Op],
62
    codeLen: u32,
63
    stack: *mut [i32],
64
    sp: u32,
65
    locals: *mut [i32],
66
    frames: *mut [Frame],
67
    frameCount: u32,
68
    pc: u32,
69
}
70
71
/// VM error types.
72
union VmError {
73
    /// Stack underflow error.
74
    StackUnderflow,
75
    /// Stack overflow error.
76
    StackOverflow,
77
    /// Division by zero.
78
    DivByZero,
79
    /// Invalid instruction or PC.
80
    InvalidPC,
81
    /// Too many nested calls.
82
    CallOverflow,
83
}
84
85
/// Push a value onto the stack.
86
fn push(vm: *mut VM, value: i32) throws (VmError) {
87
    if vm.sp >= MAX_STACK {
88
        throw VmError::StackOverflow;
89
    }
90
    vm.stack[vm.sp] = value;
91
    vm.sp += 1;
92
}
93
94
/// Pop a value from the stack.
95
fn pop(vm: *mut VM) -> i32 throws (VmError) {
96
    if vm.sp == 0 {
97
        throw VmError::StackUnderflow;
98
    }
99
    vm.sp -= 1;
100
    return vm.stack[vm.sp];
101
}
102
103
/// Peek at the top of the stack without removing.
104
fn peek(vm: *VM) -> i32 throws (VmError) {
105
    if vm.sp == 0 {
106
        throw VmError::StackUnderflow;
107
    }
108
    return vm.stack[vm.sp - 1];
109
}
110
111
/// Execute the bytecode program.
112
fn execute(vm: *mut VM) -> i32 throws (VmError) {
113
    while vm.pc < vm.codeLen {
114
        let instr = vm.code[vm.pc];
115
        vm.pc += 1;
116
117
        match instr {
118
            case Op::Push(val) => {
119
                try push(vm, val);
120
            }
121
            case Op::Add => {
122
                let b = try pop(vm);
123
                let a = try pop(vm);
124
                try push(vm, a + b);
125
            }
126
            case Op::Sub => {
127
                let b = try pop(vm);
128
                let a = try pop(vm);
129
                try push(vm, a - b);
130
            }
131
            case Op::Mul => {
132
                let b = try pop(vm);
133
                let a = try pop(vm);
134
                try push(vm, a * b);
135
            }
136
            case Op::Div => {
137
                let b = try pop(vm);
138
                let a = try pop(vm);
139
                if b == 0 {
140
                    throw VmError::DivByZero;
141
                }
142
                try push(vm, a / b);
143
            }
144
            case Op::Eq => {
145
                let b = try pop(vm);
146
                let a = try pop(vm);
147
                let mut result: i32 = 0;
148
                if a == b {
149
                    result = 1;
150
                }
151
                try push(vm, result);
152
            }
153
            case Op::Lt => {
154
                let b = try pop(vm);
155
                let a = try pop(vm);
156
                let mut result: i32 = 0;
157
                if a < b {
158
                    result = 1;
159
                }
160
                try push(vm, result);
161
            }
162
            case Op::Gt => {
163
                let b = try pop(vm);
164
                let a = try pop(vm);
165
                let mut result: i32 = 0;
166
                if a > b {
167
                    result = 1;
168
                }
169
                try push(vm, result);
170
            }
171
            case Op::Neg => {
172
                let a = try pop(vm);
173
                try push(vm, 0 - a);
174
            }
175
            case Op::Dup => {
176
                let a = try peek(vm);
177
                try push(vm, a);
178
            }
179
            case Op::Pop => {
180
                try pop(vm);
181
            }
182
            case Op::Store(idx) => {
183
                let val = try pop(vm);
184
                let mut base: u32 = 0;
185
                if vm.frameCount > 0 {
186
                    base = vm.frames[vm.frameCount - 1].localBase;
187
                }
188
                vm.locals[base + idx] = val;
189
            }
190
            case Op::Load(idx) => {
191
                let mut base: u32 = 0;
192
                if vm.frameCount > 0 {
193
                    base = vm.frames[vm.frameCount - 1].localBase;
194
                }
195
                let val = vm.locals[base + idx];
196
                try push(vm, val);
197
            }
198
            case Op::Jump(target) => {
199
                vm.pc = target;
200
            }
201
            case Op::JumpIfZero(target) => {
202
                let cond = try pop(vm);
203
                if cond == 0 {
204
                    vm.pc = target;
205
                }
206
            }
207
            case Op::Call(target) => {
208
                if vm.frameCount >= MAX_FRAMES {
209
                    throw VmError::CallOverflow;
210
                }
211
                let mut base: u32 = 0;
212
                if vm.frameCount > 0 {
213
                    base = vm.frames[vm.frameCount - 1].localBase + MAX_LOCALS;
214
                }
215
                vm.frames[vm.frameCount] = Frame { returnAddr: vm.pc, localBase: base };
216
                vm.frameCount += 1;
217
                vm.pc = target;
218
            }
219
            case Op::Ret => {
220
                if vm.frameCount == 0 {
221
                    throw VmError::InvalidPC;
222
                }
223
                vm.frameCount -= 1;
224
                vm.pc = vm.frames[vm.frameCount].returnAddr;
225
            }
226
            case Op::Halt => {
227
                return try pop(vm);
228
            }
229
        }
230
231
        if vm.pc > vm.codeLen {
232
            throw VmError::InvalidPC;
233
        }
234
    }
235
    throw VmError::InvalidPC;
236
}
237
238
/// Helper to initialize VM and run a program.
239
fn runProgram(
240
    code: *[Op],
241
    codeLen: u32,
242
    stackBuf: *mut [i32],
243
    localsBuf: *mut [i32],
244
    framesBuf: *mut [Frame]
245
) -> i32 throws (VmError) {
246
    let mut vm = VM {
247
        code,
248
        codeLen,
249
        stack: stackBuf,
250
        sp: 0,
251
        locals: localsBuf,
252
        frames: framesBuf,
253
        frameCount: 0,
254
        pc: 0,
255
    };
256
    return try execute(&mut vm);
257
}
258
259
/// Test basic arithmetic: 3 + 4 * 2 = 11
260
fn testArith(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
261
    let mut code: [Op; 8] = [Op::Halt; 8];
262
    code[0] = Op::Push(3);
263
    code[1] = Op::Push(4);
264
    code[2] = Op::Push(2);
265
    code[3] = Op::Mul;
266
    code[4] = Op::Add;
267
    code[5] = Op::Halt;
268
269
    let result: i32 = try! runProgram(&code[..], 6, stackBuf, localsBuf, framesBuf);
270
    assert result == 11;
271
    return 0;
272
}
273
274
/// Test local variables: x = 5, y = 7, push x + y.
275
fn testLocals(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
276
    let mut code: [Op; 16] = [Op::Halt; 16];
277
    code[0] = Op::Push(5);
278
    code[1] = Op::Store(0);   // x = 5
279
    code[2] = Op::Push(7);
280
    code[3] = Op::Store(1);   // y = 7
281
    code[4] = Op::Load(0);    // push x
282
    code[5] = Op::Load(1);    // push y
283
    code[6] = Op::Add;        // x + y
284
    code[7] = Op::Halt;
285
286
    let result: i32 = try! runProgram(&code[..], 8, stackBuf, localsBuf, framesBuf);
287
    assert result == 12;
288
    return 0;
289
}
290
291
/// Test conditional jump: if 3 > 2 then push 42 else push 99.
292
fn testConditional(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
293
    let mut code: [Op; 16] = [Op::Halt; 16];
294
    code[0] = Op::Push(3);
295
    code[1] = Op::Push(2);
296
    code[2] = Op::Gt;            // 3 > 2 => 1
297
    code[3] = Op::JumpIfZero(6); // if false, jump to 6
298
    code[4] = Op::Push(42);      // true branch
299
    code[5] = Op::Jump(7);       // skip false branch
300
    code[6] = Op::Push(99);      // false branch
301
    code[7] = Op::Halt;
302
303
    let result: i32 = try! runProgram(&code[..], 8, stackBuf, localsBuf, framesBuf);
304
    assert result == 42;
305
    return 0;
306
}
307
308
/// Test loop: sum 1..5 using jumps.
309
/// local[0] = counter (starts at 1), local[1] = sum (starts at 0).
310
fn testLoop(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
311
    let mut code: [Op; 32] = [Op::Halt; 32];
312
    code[0] = Op::Push(1);
313
    code[1] = Op::Store(0);      // counter = 1
314
    code[2] = Op::Push(0);
315
    code[3] = Op::Store(1);      // sum = 0
316
    // Loop start (pc = 4):
317
    code[4] = Op::Load(0);       // push counter
318
    code[5] = Op::Push(6);
319
    code[6] = Op::Lt;            // counter < 6
320
    code[7] = Op::JumpIfZero(17); // if false, exit loop
321
    code[8] = Op::Load(1);       // push sum
322
    code[9] = Op::Load(0);       // push counter
323
    code[10] = Op::Add;          // sum + counter
324
    code[11] = Op::Store(1);     // sum = sum + counter
325
    code[12] = Op::Load(0);      // push counter
326
    code[13] = Op::Push(1);
327
    code[14] = Op::Add;          // counter + 1
328
    code[15] = Op::Store(0);     // counter = counter + 1
329
    code[16] = Op::Jump(4);      // back to loop start
330
    code[17] = Op::Load(1);      // push sum
331
    code[18] = Op::Halt;
332
333
    let result: i32 = try! runProgram(&code[..], 19, stackBuf, localsBuf, framesBuf);
334
    // sum = 1+2+3+4+5 = 15
335
    assert result == 15;
336
    return 0;
337
}
338
339
/// Test function call: call a function that computes n*2+1 for n=10.
340
fn testCall(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
341
    let mut code: [Op; 32] = [Op::Halt; 32];
342
343
    // Main: push argument on stack, call function, halt.
344
    code[0] = Op::Push(10);      // push argument
345
    code[1] = Op::Call(5);       // call function at 5
346
    // After return, result is on stack.
347
    code[2] = Op::Halt;
348
    code[3] = Op::Halt;          // padding
349
    code[4] = Op::Halt;          // padding
350
351
    // Function at pc 5:
352
    code[5] = Op::Store(0);      // pop arg into local[0]
353
    code[6] = Op::Load(0);       // push local[0]
354
    code[7] = Op::Push(2);
355
    code[8] = Op::Mul;           // n * 2
356
    code[9] = Op::Push(1);
357
    code[10] = Op::Add;          // n * 2 + 1
358
    code[11] = Op::Ret;          // return (result on stack)
359
360
    let result: i32 = try! runProgram(&code[..], 12, stackBuf, localsBuf, framesBuf);
361
    // 10 * 2 + 1 = 21
362
    assert result == 21;
363
    return 0;
364
}
365
366
/// Test division by zero detection using try...catch with error binding.
367
fn testDivByZero(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
368
    let mut code: [Op; 8] = [Op::Halt; 8];
369
    code[0] = Op::Push(42);
370
    code[1] = Op::Push(0);
371
    code[2] = Op::Div;
372
    code[3] = Op::Halt;
373
374
    let mut caught: i32 = 0;
375
    try runProgram(&code[..], 4, stackBuf, localsBuf, framesBuf) catch e {
376
        if e == VmError::DivByZero {
377
            caught = 1;
378
        } else {
379
            caught = 2;
380
        }
381
    };
382
    assert caught == 1;
383
    return 0;
384
}
385
386
/// Test negation and equality.
387
fn testNegAndEq(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
388
    let mut code: [Op; 16] = [Op::Halt; 16];
389
    code[0] = Op::Push(5);
390
    code[1] = Op::Neg;           // -5
391
    code[2] = Op::Push(-5);
392
    code[3] = Op::Eq;            // -5 == -5 => 1
393
    code[4] = Op::Halt;
394
395
    let result: i32 = try! runProgram(&code[..], 5, stackBuf, localsBuf, framesBuf);
396
    assert result == 1;
397
    return 0;
398
}
399
400
/// Test factorial using recursive calls: fact(6) = 720.
401
fn testFactorial(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
402
    let mut code: [Op; 32] = [Op::Halt; 32];
403
404
    // Main: push 6, call fact, halt.
405
    code[0] = Op::Push(6);
406
    code[1] = Op::Call(4);       // call fact at 4
407
    code[2] = Op::Halt;
408
    code[3] = Op::Halt;          // padding
409
410
    // fact(n) at pc 4:
411
    //   Store arg to local[0]
412
    //   If n <= 1, push 1, return
413
    //   Else push n, push fact(n-1), multiply, return
414
    code[4] = Op::Store(0);      // local[0] = n
415
    code[5] = Op::Load(0);       // push n
416
    code[6] = Op::Push(2);
417
    code[7] = Op::Lt;            // n < 2
418
    code[8] = Op::JumpIfZero(11); // if n >= 2, skip
419
    code[9] = Op::Push(1);       // base case: push 1
420
    code[10] = Op::Ret;
421
422
    // Recursive case:
423
    code[11] = Op::Load(0);      // push n
424
    code[12] = Op::Push(1);
425
    code[13] = Op::Sub;          // n - 1
426
    code[14] = Op::Call(4);      // fact(n-1)
427
    code[15] = Op::Load(0);      // push n
428
    code[16] = Op::Mul;          // fact(n-1) * n
429
    code[17] = Op::Ret;
430
431
    let result: i32 = try! runProgram(&code[..], 18, stackBuf, localsBuf, framesBuf);
432
    assert result == 720;
433
    return 0;
434
}
435
436
/// Test dup instruction.
437
fn testDup(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
438
    let mut code: [Op; 8] = [Op::Halt; 8];
439
    code[0] = Op::Push(7);
440
    code[1] = Op::Dup;
441
    code[2] = Op::Add;           // 7 + 7 = 14
442
    code[3] = Op::Halt;
443
444
    let result: i32 = try! runProgram(&code[..], 4, stackBuf, localsBuf, framesBuf);
445
    assert result == 14;
446
    return 0;
447
}
448
449
/// Test stack underflow detection using try...catch with error binding.
450
fn testStackUnderflow(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
451
    let mut code: [Op; 4] = [Op::Halt; 4];
452
    code[0] = Op::Add;  // nothing on stack
453
    code[1] = Op::Halt;
454
455
    let mut caught: i32 = 0;
456
    try runProgram(&code[..], 2, stackBuf, localsBuf, framesBuf) catch e {
457
        if e == VmError::StackUnderflow {
458
            caught = 1;
459
        } else {
460
            caught = 2;
461
        }
462
    };
463
    assert caught == 1;
464
    return 0;
465
}
466
467
/// Test that try...catch on success path does not execute catch block.
468
fn testSuccessNoCatch(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
469
    let mut code: [Op; 4] = [Op::Halt; 4];
470
    code[0] = Op::Push(99);
471
    code[1] = Op::Halt;
472
473
    let mut caught: i32 = 0;
474
    let result: i32 = try runProgram(&code[..], 2, stackBuf, localsBuf, framesBuf) catch e {
475
        caught = 1;
476
        return 1;
477
    };
478
    // Catch block should not have run.
479
    assert caught == 0;
480
    // Should have the success value.
481
    assert result == 99;
482
    return 0;
483
}
484
485
/// Test call overflow detection by exhausting frames.
486
fn testCallOverflow(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
487
    let mut code: [Op; 4] = [Op::Halt; 4];
488
    // Infinite recursion: function calls itself.
489
    code[0] = Op::Call(0);
490
    code[1] = Op::Halt;
491
492
    let mut caught: i32 = 0;
493
    try runProgram(&code[..], 2, stackBuf, localsBuf, framesBuf) catch e {
494
        if e == VmError::CallOverflow {
495
            caught = 1;
496
        } else {
497
            caught = 2;
498
        }
499
    };
500
    assert caught == 1;
501
    return 0;
502
}
503
504
/// Test that catch with no binding works (discard the error).
505
fn testCatchNoBinding(stackBuf: *mut [i32], localsBuf: *mut [i32], framesBuf: *mut [Frame]) -> i32 {
506
    let mut code: [Op; 4] = [Op::Halt; 4];
507
    code[0] = Op::Pop;  // underflow
508
    code[1] = Op::Halt;
509
510
    // Catch without binding - just swallow the error.
511
    try runProgram(&code[..], 2, stackBuf, localsBuf, framesBuf) catch {};
512
    return 0;
513
}
514
515
@default fn main() -> i32 {
516
    let mut stackBuf: [i32; 64] = [0; 64];
517
    let mut localsBuf: [i32; 128] = [0; 128];
518
    let mut framesBuf: [Frame; 8] = [Frame { returnAddr: 0, localBase: 0 }; 8];
519
520
    let r1 = testArith(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
521
    if r1 != 0 {
522
        return 10 + r1;
523
    }
524
525
    let r2 = testLocals(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
526
    if r2 != 0 {
527
        return 20 + r2;
528
    }
529
530
    let r3 = testConditional(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
531
    if r3 != 0 {
532
        return 30 + r3;
533
    }
534
535
    let r4 = testLoop(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
536
    if r4 != 0 {
537
        return 40 + r4;
538
    }
539
540
    let r5 = testCall(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
541
    if r5 != 0 {
542
        return 50 + r5;
543
    }
544
545
    let r6 = testDivByZero(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
546
    if r6 != 0 {
547
        return 60 + r6;
548
    }
549
550
    let r7 = testNegAndEq(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
551
    if r7 != 0 {
552
        return 70 + r7;
553
    }
554
555
    let r8 = testFactorial(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
556
    if r8 != 0 {
557
        return 80 + r8;
558
    }
559
560
    let r9 = testDup(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
561
    if r9 != 0 {
562
        return 90 + r9;
563
    }
564
565
    let r10 = testStackUnderflow(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
566
    if r10 != 0 {
567
        return 100 + r10;
568
    }
569
570
    let r11 = testSuccessNoCatch(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
571
    if r11 != 0 {
572
        return 110 + r11;
573
    }
574
575
    let r12 = testCallOverflow(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
576
    if r12 != 0 {
577
        return 120 + r12;
578
    }
579
580
    let r13 = testCatchNoBinding(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
581
    if r13 != 0 {
582
        return 130 + r13;
583
    }
584
585
    return 0;
586
}