test: Exercise linear type semantics
f18cc5f05fced3906cb0eb4c693b33e59b65db23ab77b3090005cfb2c4482ff4
1 parent
a8787514
test/tests/linear.let-else.rad
added
+16 -0
| 1 | + | //! returns: 42 |
|
| 2 | + | ||
| 3 | + | /// Return the optional value or a default. |
|
| 4 | + | fn fallback(value: ?u32) -> u32 { |
|
| 5 | + | let item = value else 40; |
|
| 6 | + | return item; |
|
| 7 | + | } |
|
| 8 | + | ||
| 9 | + | /// Exercise value-producing and case-pattern `let-else`. |
|
| 10 | + | @default fn main() -> u32 { |
|
| 11 | + | let expected: u32 = 1; |
|
| 12 | + | let actual: u32 = 2; |
|
| 13 | + | let case expected = actual else fallback(nil); |
|
| 14 | + | assert expected == 1; |
|
| 15 | + | return fallback(nil) + fallback(2); |
|
| 16 | + | } |
test/tests/linear.ownership.rad
added
+19 -0
| 1 | + | //! returns: 42 |
|
| 2 | + | ||
| 3 | + | /// Linear token consumed by the test. |
|
| 4 | + | union Token: Linear { |
|
| 5 | + | Value(u32), |
|
| 6 | + | } |
|
| 7 | + | ||
| 8 | + | /// Consume a token and return its payload. |
|
| 9 | + | fn consume(token: Token) -> u32 { |
|
| 10 | + | match token { |
|
| 11 | + | case Token::Value(value) => return value, |
|
| 12 | + | } |
|
| 13 | + | } |
|
| 14 | + | ||
| 15 | + | /// Exercise linear ownership. |
|
| 16 | + | @default fn main() -> u32 { |
|
| 17 | + | let token = Token::Value(42); |
|
| 18 | + | return consume(token); |
|
| 19 | + | } |
test/tests/linear.ownership.ril
added
+23 -0
| 1 | + | fn w32 $consume(w64 %0) { |
|
| 2 | + | @entry0 |
|
| 3 | + | reserve %1 8 4; |
|
| 4 | + | blit %1 %0 8; |
|
| 5 | + | jmp @arm1; |
|
| 6 | + | @arm1 |
|
| 7 | + | jmp @case2; |
|
| 8 | + | @case2 |
|
| 9 | + | load w32 %2 %1 4; |
|
| 10 | + | ret %2; |
|
| 11 | + | } |
|
| 12 | + | ||
| 13 | + | fn w32 $main() { |
|
| 14 | + | @entry0 |
|
| 15 | + | reserve %0 4 4; |
|
| 16 | + | store w32 42 %0 0; |
|
| 17 | + | reserve %1 8 4; |
|
| 18 | + | store w8 0 %1 0; |
|
| 19 | + | add w64 %2 %1 4; |
|
| 20 | + | blit %2 %0 4; |
|
| 21 | + | call w32 %3 $consume(%1); |
|
| 22 | + | ret %3; |
|
| 23 | + | } |
test/tests/linear.reference.rad
added
+28 -0
| 1 | + | //! returns: 42 |
|
| 2 | + | ||
| 3 | + | /// Linear counter borrowed and consumed by the test. |
|
| 4 | + | union Counter: Linear { |
|
| 5 | + | Value(u32), |
|
| 6 | + | } |
|
| 7 | + | ||
| 8 | + | /// Increment a borrowed counter. |
|
| 9 | + | fn increment(counter: &mut Counter) { |
|
| 10 | + | match counter { |
|
| 11 | + | case Counter::Value(value) => set *value += 1, |
|
| 12 | + | } |
|
| 13 | + | } |
|
| 14 | + | ||
| 15 | + | /// Consume a counter and return its value. |
|
| 16 | + | fn consume(counter: Counter) -> u32 { |
|
| 17 | + | match counter { |
|
| 18 | + | case Counter::Value(value) => return value, |
|
| 19 | + | } |
|
| 20 | + | } |
|
| 21 | + | ||
| 22 | + | /// Exercise mutable references to linear values. |
|
| 23 | + | @default fn main() -> u32 { |
|
| 24 | + | let mut counter = Counter::Value(40); |
|
| 25 | + | increment(&mut counter); |
|
| 26 | + | increment(&mut counter); |
|
| 27 | + | return consume(counter); |
|
| 28 | + | } |
test/tests/linear.reference.ril
added
+40 -0
| 1 | + | fn w64 $increment(w64 %0) { |
|
| 2 | + | @entry0 |
|
| 3 | + | jmp @arm1; |
|
| 4 | + | @arm1 |
|
| 5 | + | jmp @case2; |
|
| 6 | + | @case2 |
|
| 7 | + | add w64 %1 %0 4; |
|
| 8 | + | load w32 %2 %1 0; |
|
| 9 | + | add w32 %3 %2 1; |
|
| 10 | + | store w32 %3 %1 0; |
|
| 11 | + | jmp @merge4; |
|
| 12 | + | @merge4 |
|
| 13 | + | ret; |
|
| 14 | + | } |
|
| 15 | + | ||
| 16 | + | fn w32 $consume(w64 %0) { |
|
| 17 | + | @entry0 |
|
| 18 | + | reserve %1 8 4; |
|
| 19 | + | blit %1 %0 8; |
|
| 20 | + | jmp @arm1; |
|
| 21 | + | @arm1 |
|
| 22 | + | jmp @case2; |
|
| 23 | + | @case2 |
|
| 24 | + | load w32 %2 %1 4; |
|
| 25 | + | ret %2; |
|
| 26 | + | } |
|
| 27 | + | ||
| 28 | + | fn w32 $main() { |
|
| 29 | + | @entry0 |
|
| 30 | + | reserve %0 4 4; |
|
| 31 | + | store w32 40 %0 0; |
|
| 32 | + | reserve %1 8 4; |
|
| 33 | + | store w8 0 %1 0; |
|
| 34 | + | add w64 %2 %1 4; |
|
| 35 | + | blit %2 %0 4; |
|
| 36 | + | call w64 $increment(%1); |
|
| 37 | + | call w64 $increment(%1); |
|
| 38 | + | call w32 %3 $consume(%1); |
|
| 39 | + | ret %3; |
|
| 40 | + | } |
test/tests/linear.unsafe.rad
added
+21 -0
| 1 | + | //! returns: 42 |
|
| 2 | + | ||
| 3 | + | /// Linear marker that enables linear checking. |
|
| 4 | + | record Marker: Linear {} |
|
| 5 | + | ||
| 6 | + | /// Load a value through an unsafe pointer. |
|
| 7 | + | unsafe fn load(pointer: *unsafe u32) -> u32 { |
|
| 8 | + | return *pointer; |
|
| 9 | + | } |
|
| 10 | + | ||
| 11 | + | /// Store a value through an unsafe pointer. |
|
| 12 | + | unsafe fn store(pointer: *unsafe mut u32, value: u32) { |
|
| 13 | + | set *pointer = value; |
|
| 14 | + | } |
|
| 15 | + | ||
| 16 | + | /// Exercise unsafe pointer loads and stores. |
|
| 17 | + | @default unsafe fn main() -> u32 { |
|
| 18 | + | let mut value: u32 = 0; |
|
| 19 | + | store(&mut value as *unsafe mut u32, 42); |
|
| 20 | + | return load(&value as *unsafe u32); |
|
| 21 | + | } |
test/tests/linear.unsafe.ril
added
+20 -0
| 1 | + | fn w32 $load(w64 %0) { |
|
| 2 | + | @entry0 |
|
| 3 | + | load w32 %1 %0 0; |
|
| 4 | + | ret %1; |
|
| 5 | + | } |
|
| 6 | + | ||
| 7 | + | fn w64 $store(w64 %0, w32 %1) { |
|
| 8 | + | @entry0 |
|
| 9 | + | store w32 %1 %0 0; |
|
| 10 | + | ret; |
|
| 11 | + | } |
|
| 12 | + | ||
| 13 | + | fn w32 $main() { |
|
| 14 | + | @entry0 |
|
| 15 | + | reserve %0 4 4; |
|
| 16 | + | store w32 0 %0 0; |
|
| 17 | + | call w64 $store(%0, 42); |
|
| 18 | + | call w32 %1 $load(%0); |
|
| 19 | + | ret %1; |
|
| 20 | + | } |