compiler/
lib/
examples/
std/
arch/
rv64/
asm/
scanner/
tests.rad
6.8 KiB
emit.rad
8.8 KiB
parser.rad
32.9 KiB
scanner.rad
9.1 KiB
tests.rad
10.0 KiB
image/
shared/
asm.rad
24.8 KiB
atomicTests.rad
5.0 KiB
atomics.rad
3.6 KiB
bounds.rad
21.0 KiB
decode.rad
15.2 KiB
emit.rad
33.2 KiB
encode.rad
22.0 KiB
image.rad
4.5 KiB
isel.rad
52.1 KiB
printer.rad
13.9 KiB
shared.rad
16.8 KiB
tests.rad
17.2 KiB
rv64.rad
17.5 KiB
char/
collections/
lang/
sys/
arch.rad
68 B
char.rad
855 B
collections.rad
39 B
fmt.rad
8.3 KiB
intrinsics.rad
467 B
io.rad
1.7 KiB
lang.rad
276 B
mem.rad
2.3 KiB
sys.rad
179 B
testing.rad
2.4 KiB
tests.rad
15.7 KiB
vec.rad
3.2 KiB
std.rad
281 B
scripts/
seed/
sublime/
test/
vim/
.gitignore
336 B
.gitsigners
112 B
CONTRIBUTING
2.1 KiB
LICENSE
1.1 KiB
Makefile
5.4 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.5 KiB
std.lib.test
662 B
lib/std/arch/rv64/asm/scanner/tests.rad
raw
| 1 | use std::mem; |
| 2 | use std::testing; |
| 3 | use std::lang::strings; |
| 4 | |
| 5 | /// String pool used by assembler scanner tests. |
| 6 | static TEST_STRING_POOL: strings::Pool = strings::Pool { table: [""; 32768], count: 0 }; |
| 7 | |
| 8 | /// Create a scanner for test input. |
| 9 | fn testScanner(source: *[u8]) -> super::Scanner { |
| 10 | return super::scanner(super::SourceKind::String, source); |
| 11 | } |
| 12 | |
| 13 | /// Scanner recognizes assembler-specific sigils and scoped names. |
| 14 | @test fn testScanRegisterDirectiveAndLabelTokens() throws (testing::TestError) { |
| 15 | let mut s = testScanner( |
| 16 | ".text %sp @entry name::tail 42" |
| 17 | ); |
| 18 | let directive = super::next(&mut s, &mut TEST_STRING_POOL); |
| 19 | try testing::expect(directive.kind == super::TokenKind::Directive); |
| 20 | try testing::expect(mem::eq(directive.source, ".text")); |
| 21 | |
| 22 | let reg = super::next(&mut s, &mut TEST_STRING_POOL); |
| 23 | try testing::expect(reg.kind == super::TokenKind::Register); |
| 24 | try testing::expect(mem::eq(reg.source, "%sp")); |
| 25 | |
| 26 | let label = super::next(&mut s, &mut TEST_STRING_POOL); |
| 27 | try testing::expect(label.kind == super::TokenKind::Label); |
| 28 | try testing::expect(mem::eq(label.source, "@entry")); |
| 29 | |
| 30 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 31 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::ColonColon); |
| 32 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 33 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Number); |
| 34 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Eof); |
| 35 | } |
| 36 | |
| 37 | /// Keyword-shaped text remains plain assembler identifiers. |
| 38 | @test fn testScanKeywordShapedAsmNamesRemainAsmTokens() throws (testing::TestError) { |
| 39 | let mut s = testScanner( |
| 40 | "and or not align addi .text @label" |
| 41 | ); |
| 42 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 43 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 44 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 45 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 46 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Ident); |
| 47 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Directive); |
| 48 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Label); |
| 49 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Eof); |
| 50 | } |
| 51 | |
| 52 | /// Quoted labels can spell symbol names that are not identifier-shaped. |
| 53 | @test fn testScanQuotedLabelToken() throws (testing::TestError) { |
| 54 | let mut s = testScanner( |
| 55 | "@\"foo.bar.baz\"" |
| 56 | ); |
| 57 | let label = super::next(&mut s, &mut TEST_STRING_POOL); |
| 58 | try testing::expect(label.kind == super::TokenKind::QuotedLabel); |
| 59 | try testing::expect(mem::eq(label.source, "@\"foo.bar.baz\"")); |
| 60 | try testing::expect(super::next(&mut s, &mut TEST_STRING_POOL).kind == super::TokenKind::Eof); |
| 61 | } |
| 62 | |
| 63 | /// Sigil-prefixed tokens require the name to start immediately after the sigil. |
| 64 | @test fn testScanSigilsRequireAdjacency() throws (testing::TestError) { |
| 65 | let mut regScan = testScanner("% a0"); |
| 66 | try testing::expect(super::next(&mut regScan, &mut TEST_STRING_POOL).kind == super::TokenKind::Invalid); |
| 67 | |
| 68 | let mut labelScan = testScanner("@ entry"); |
| 69 | try testing::expect(super::next(&mut labelScan, &mut TEST_STRING_POOL).kind == super::TokenKind::Invalid); |
| 70 | |
| 71 | let mut directiveScan = testScanner(". text"); |
| 72 | try testing::expect(super::next(&mut directiveScan, &mut TEST_STRING_POOL).kind == super::TokenKind::Invalid); |
| 73 | } |
| 74 | |
| 75 | /// Scanner reaches EOF after trailing whitespace and comments. |
| 76 | @test fn testScanProgramEndingWithNewline() throws (testing::TestError) { |
| 77 | let mut s = testScanner( |
| 78 | ".text;\n@start\naddi %a0 %zero 42;\nsd %a0 8(%sp);\n// comment\nbeq %a0 %zero @done;\n@done\nret;\n" |
| 79 | ); |
| 80 | loop { |
| 81 | let tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 82 | if tok.kind == super::TokenKind::Eof { |
| 83 | try testing::expect(tok.source.len == 0); |
| 84 | return; |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | /// Signed numbers scan only the numeric formats supported by the assembler scanner. |
| 90 | @test fn testScanSignedHexAndUnsupportedNumericForms() throws (testing::TestError) { |
| 91 | let mut s = testScanner( |
| 92 | "+0x2a -0b10 45.5" |
| 93 | ); |
| 94 | let mut tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 95 | try testing::expect(tok.kind == super::TokenKind::Number); |
| 96 | try testing::expect(mem::eq(tok.source, "+0x2a")); |
| 97 | |
| 98 | set tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 99 | try testing::expect(tok.kind == super::TokenKind::Number); |
| 100 | try testing::expect(mem::eq(tok.source, "-0")); |
| 101 | |
| 102 | set tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 103 | try testing::expect(tok.kind == super::TokenKind::Ident); |
| 104 | try testing::expect(mem::eq(tok.source, "b10")); |
| 105 | |
| 106 | set tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 107 | try testing::expect(tok.kind == super::TokenKind::Number); |
| 108 | try testing::expect(mem::eq(tok.source, "45")); |
| 109 | |
| 110 | set tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 111 | try testing::expect(tok.kind == super::TokenKind::Invalid); |
| 112 | try testing::expect(mem::eq(tok.source, "expected directive name after `.`")); |
| 113 | |
| 114 | set tok = super::next(&mut s, &mut TEST_STRING_POOL); |
| 115 | try testing::expect(tok.kind == super::TokenKind::Number); |
| 116 | try testing::expect(mem::eq(tok.source, "5")); |
| 117 | } |
| 118 | |
| 119 | /// Unterminated string and character literals report invalid tokens. |
| 120 | @test fn testScanUnterminatedDelimitedLiterals() throws (testing::TestError) { |
| 121 | let mut stringScan = testScanner("\"unterminated"); |
| 122 | let stringTok = super::next(&mut stringScan, &mut TEST_STRING_POOL); |
| 123 | try testing::expect(stringTok.kind == super::TokenKind::Invalid); |
| 124 | try testing::expect(mem::eq(stringTok.source, "unterminated string")); |
| 125 | |
| 126 | let mut escapedStringScan = testScanner("\"unterminated\\"); |
| 127 | let escapedStringTok = super::next(&mut escapedStringScan, &mut TEST_STRING_POOL); |
| 128 | try testing::expect(escapedStringTok.kind == super::TokenKind::Invalid); |
| 129 | try testing::expect(mem::eq(escapedStringTok.source, "unterminated string")); |
| 130 | |
| 131 | let mut charScan = testScanner("'x"); |
| 132 | let charTok = super::next(&mut charScan, &mut TEST_STRING_POOL); |
| 133 | try testing::expect(charTok.kind == super::TokenKind::Invalid); |
| 134 | try testing::expect(mem::eq(charTok.source, "unterminated character")); |
| 135 | |
| 136 | let mut escapedCharScan = testScanner("'\\"); |
| 137 | let escapedCharTok = super::next(&mut escapedCharScan, &mut TEST_STRING_POOL); |
| 138 | try testing::expect(escapedCharTok.kind == super::TokenKind::Invalid); |
| 139 | try testing::expect(mem::eq(escapedCharTok.source, "unterminated character")); |
| 140 | } |