compiler/
lib/
examples/
std/
arch/
rv64/
asm/
scanner/
tests.rad
6.1 KiB
emit.rad
8.2 KiB
parser.rad
29.8 KiB
scanner.rad
9.0 KiB
tests.rad
6.3 KiB
asm.rad
22.6 KiB
decode.rad
14.3 KiB
emit.rad
26.0 KiB
encode.rad
21.5 KiB
isel.rad
47.0 KiB
printer.rad
12.6 KiB
tests.rad
17.1 KiB
rv64.rad
11.9 KiB
char/
collections/
lang/
sys/
arch.rad
68 B
char.rad
855 B
collections.rad
39 B
fmt.rad
8.5 KiB
intrinsics.rad
391 B
io.rad
1.3 KiB
lang.rad
258 B
mem.rad
2.2 KiB
sys.rad
173 B
testing.rad
2.4 KiB
tests.rad
14.8 KiB
vec.rad
3.2 KiB
std.rad
281 B
scripts/
seed/
sublime/
test/
vim/
.gitignore
366 B
.gitsigners
112 B
LICENSE
1.1 KiB
Makefile
3.6 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.2 KiB
std.lib.test
347 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: undefined, 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, &mut TEST_STRING_POOL); |
| 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); |
| 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); |
| 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); |
| 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).kind == super::TokenKind::Ident); |
| 31 | try testing::expect(super::next(&mut s).kind == super::TokenKind::ColonColon); |
| 32 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident); |
| 33 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Number); |
| 34 | try testing::expect(super::next(&mut s).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).kind == super::TokenKind::Ident); |
| 43 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident); |
| 44 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident); |
| 45 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident); |
| 46 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident); |
| 47 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Directive); |
| 48 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Label); |
| 49 | try testing::expect(super::next(&mut s).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); |
| 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).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).kind == super::TokenKind::Invalid); |
| 67 | |
| 68 | let mut labelScan = testScanner("@ entry"); |
| 69 | try testing::expect(super::next(&mut labelScan).kind == super::TokenKind::Invalid); |
| 70 | |
| 71 | let mut directiveScan = testScanner(". text"); |
| 72 | try testing::expect(super::next(&mut directiveScan).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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 138 | try testing::expect(escapedCharTok.kind == super::TokenKind::Invalid); |
| 139 | try testing::expect(mem::eq(escapedCharTok.source, "unterminated character")); |
| 140 | } |