Add more tests for RGBASM code coverage (#1257)

* Add more tests for RGBASM code coverage

* Use C++ unnamed parameters, not `(void)` casting

* Fix crash in `sect_AlignPC` from #1253
This commit is contained in:
Rangi
2023-12-01 10:21:43 -05:00
committed by GitHub
parent cee3d1c859
commit 6132b77c1e
85 changed files with 450 additions and 65 deletions

View File

@@ -130,9 +130,8 @@ void out_RegisterNode(struct FileStackNode *node)
} }
} }
void out_ReplaceNode(struct FileStackNode *node) void out_ReplaceNode(struct FileStackNode * /* node */)
{ {
(void)node;
#if 0 #if 0
This is code intended to replace a node, which is pretty useless until ref counting is added... This is code intended to replace a node, which is pretty useless until ref counting is added...
@@ -469,10 +468,8 @@ static void writeFileStackNode(struct FileStackNode const *node, FILE *f)
} }
} }
static void registerUnregisteredSymbol(struct Symbol *symbol, void *arg) static void registerUnregisteredSymbol(struct Symbol *symbol, void *)
{ {
(void)arg; // sym_ForEach requires a void* parameter, but we are not using it.
// Check for symbol->src, to skip any built-in symbol from rgbasm // Check for symbol->src, to skip any built-in symbol from rgbasm
if (symbol->src && symbol->ID == (uint32_t)-1) { if (symbol->src && symbol->ID == (uint32_t)-1) {
registerSymbol(symbol); registerSymbol(symbol);

View File

@@ -1021,6 +1021,7 @@ align : T_OP_ALIGN align_spec { sect_AlignPC($2.alignment, $2.alignOfs); }
align_spec : uconst { align_spec : uconst {
if ($1 > 16) { if ($1 > 16) {
error("Alignment must be between 0 and 16, not %u\n", $1); error("Alignment must be between 0 and 16, not %u\n", $1);
$$.alignment = $$.alignOfs = 0;
} else { } else {
$$.alignment = $1; $$.alignment = $1;
$$.alignOfs = 0; $$.alignOfs = 0;
@@ -1029,10 +1030,12 @@ align_spec : uconst {
| uconst T_COMMA const { | uconst T_COMMA const {
if ($1 > 16) { if ($1 > 16) {
error("Alignment must be between 0 and 16, not %u\n", $1); error("Alignment must be between 0 and 16, not %u\n", $1);
$$.alignment = $$.alignOfs = 0;
} else if ($3 <= -(1 << $1) || $3 >= 1 << $1) { } else if ($3 <= -(1 << $1) || $3 >= 1 << $1) {
error("The absolute alignment offset (%" PRIu32 error("The absolute alignment offset (%" PRIu32
") must be less than alignment size (%d)\n", ") must be less than alignment size (%d)\n",
(uint32_t)($3 < 0 ? -$3 : $3), 1 << $1); (uint32_t)($3 < 0 ? -$3 : $3), 1 << $1);
$$.alignment = $$.alignOfs = 0;
} else { } else {
$$.alignment = $1; $$.alignment = $1;
$$.alignOfs = $3 < 0 ? (1 << $1) + $3 : $3; $$.alignOfs = $3 < 0 ? (1 << $1) + $3 : $3;

View File

@@ -512,9 +512,6 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
if (src2->val < 0) if (src2->val < 0)
fatalerror("Exponentiation by negative power\n"); fatalerror("Exponentiation by negative power\n");
if (src1->val == INT32_MIN && src2->val == -1)
expr->val = 0;
else
expr->val = op_exponent(src1->val, src2->val); expr->val = op_exponent(src1->val, src2->val);
break; break;

View File

@@ -167,10 +167,9 @@ static unsigned int mergeSectUnion(struct Section *sect, enum SectionType type,
return nbSectErrors; return nbSectErrors;
} }
static unsigned int mergeFragments(struct Section *sect, enum SectionType type, uint32_t org, static unsigned int mergeFragments(struct Section *sect, uint32_t org, uint8_t alignment,
uint8_t alignment, uint16_t alignOffset) uint16_t alignOffset)
{ {
(void)type;
assert(alignment < 16); // Should be ensured by the caller assert(alignment < 16); // Should be ensured by the caller
unsigned int nbSectErrors = 0; unsigned int nbSectErrors = 0;
@@ -183,8 +182,7 @@ static unsigned int mergeFragments(struct Section *sect, enum SectionType type,
// If both are fixed, they must be the same // If both are fixed, they must be the same
if (sect->org != (uint32_t)-1 && sect->org != curOrg) if (sect->org != (uint32_t)-1 && sect->org != curOrg)
fail("Section already declared as fixed at incompatible address $%04" fail("Section already declared as fixed at incompatible address $%04"
PRIx32 " (cur addr = %04" PRIx32 ")\n", PRIx32 "\n", sect->org);
sect->org, sect->org + sect->size);
else if (sect->align != 0 && (mask(sect->align) & (curOrg - sect->alignOfs))) else if (sect->align != 0 && (mask(sect->align) & (curOrg - sect->alignOfs)))
fail("Section already declared as aligned to %u bytes (offset %" fail("Section already declared as aligned to %u bytes (offset %"
PRIu16 ")\n", 1U << sect->align, sect->alignOfs); PRIu16 ")\n", 1U << sect->align, sect->alignOfs);
@@ -232,8 +230,9 @@ static void mergeSections(struct Section *sect, enum SectionType type, uint32_t
switch (mod) { switch (mod) {
case SECTION_UNION: case SECTION_UNION:
case SECTION_FRAGMENT: case SECTION_FRAGMENT:
nbSectErrors += (mod == SECTION_UNION ? mergeSectUnion : mergeFragments) nbSectErrors += mod == SECTION_UNION ?
(sect, type, org, alignment, alignOffset); mergeSectUnion(sect, type, org, alignment, alignOffset) :
mergeFragments(sect, org, alignment, alignOffset);
// Common checks // Common checks
@@ -499,7 +498,7 @@ void sect_AlignPC(uint8_t alignment, uint16_t offset)
return; return;
struct Section *sect = sect_GetSymbolSection(); struct Section *sect = sect_GetSymbolSection();
uint16_t alignSize = 1 << alignment; // Size of an aligned "block" uint32_t alignSize = 1 << alignment; // Size of an aligned "block"
if (sect->org != (uint32_t)-1) { if (sect->org != (uint32_t)-1) {
if ((sect->org + curOffset - offset) % alignSize) if ((sect->org + curOffset - offset) % alignSize)

View File

@@ -328,9 +328,8 @@ static struct UnassignedSection *sections;
* @param section The section to categorize * @param section The section to categorize
* @param arg Callback arg, unused * @param arg Callback arg, unused
*/ */
static void categorizeSection(struct Section *section, void *arg) static void categorizeSection(struct Section *section, void *)
{ {
(void)arg;
uint8_t constraints = 0; uint8_t constraints = 0;
if (section->isBankFixed) if (section->isBankFixed)

View File

@@ -406,7 +406,6 @@ int main(int argc, char *argv[])
break; break;
case 's': case 's':
// TODO: implement "smart linking" with `-s` // TODO: implement "smart linking" with `-s`
(void)musl_optarg;
warning(NULL, 0, "Nobody has any idea what `-s` does"); warning(NULL, 0, "Nobody has any idea what `-s` does");
break; break;
case 't': case 't':

View File

@@ -669,10 +669,8 @@ static void freeNode(struct FileStackNode *node)
free(node->name); free(node->name);
} }
static void freeSection(struct Section *section, void *arg) static void freeSection(struct Section *section, void *)
{ {
(void)arg;
do { do {
struct Section *next = section->nextu; struct Section *next = section->nextu;

View File

@@ -502,8 +502,8 @@ void patch_CheckAssertions(struct Assertion *assert)
/* /*
* Applies all of a section's patches * Applies all of a section's patches
* @param section The section to patch * @param section The section component to patch
* @param arg Ignored callback arg * @param dataSection The section to patch
*/ */
static void applyFilePatches(struct Section *section, struct Section *dataSection) static void applyFilePatches(struct Section *section, struct Section *dataSection)
{ {
@@ -554,23 +554,17 @@ static void applyFilePatches(struct Section *section, struct Section *dataSectio
} }
/* /*
* Applies all of a section's patches, iterating over "components" of * Applies all of a section's patches, iterating over "components" of unionized sections
* unionized sections
* @param section The section to patch * @param section The section to patch
* @param arg Ignored callback arg * @param arg Ignored callback arg
*/ */
static void applyPatches(struct Section *section, void *arg) static void applyPatches(struct Section *section, void *)
{ {
if (!sect_HasData(section->type)) if (!sect_HasData(section->type))
return; return;
(void)arg; for (struct Section *component = section; component; component = component->nextu)
struct Section *dataSection = section; applyFilePatches(component, section);
do {
applyFilePatches(section, dataSection);
section = section->nextu;
} while (section);
} }
void patch_ApplyPatches(void) void patch_ApplyPatches(void)

View File

@@ -219,10 +219,8 @@ void sect_CleanupSections(void)
hash_EmptyMap(sections); hash_EmptyMap(sections);
} }
static void doSanityChecks(struct Section *section, void *ptr) static void doSanityChecks(struct Section *section, void *)
{ {
(void)ptr;
// Sanity check the section's type // Sanity check the section's type
if (section->type < 0 || section->type >= SECTTYPE_INVALID) { if (section->type < 0 || section->type >= SECTTYPE_INVALID) {

View File

@@ -5,6 +5,10 @@ SECTION "Anonymous label errors test", ROM0
db :-- ; Reference goes too far back db :-- ; Reference goes too far back
: ; Can't EXPORT or PURGE anonymous labels
EXPORT :-
PURGE :-
; Uncomment this if you're a badass with a *lot* of RAM ; Uncomment this if you're a badass with a *lot* of RAM
; REPT 2147483647 ; REPT 2147483647
; : ; :

View File

@@ -2,6 +2,10 @@ error: anon-label-bad.asm(2):
Label "!0" created outside of a SECTION Label "!0" created outside of a SECTION
error: anon-label-bad.asm(6): error: anon-label-bad.asm(6):
Reference to anonymous label 2 before, when only 1 has been created so far Reference to anonymous label 2 before, when only 1 has been created so far
error: anon-label-bad.asm(18): error: anon-label-bad.asm(9):
syntax error, unexpected anonymous label, expecting label or identifier or local identifier
error: anon-label-bad.asm(10):
syntax error, unexpected anonymous label, expecting label or identifier or local identifier
error: anon-label-bad.asm(22):
syntax error, unexpected :: syntax error, unexpected ::
error: Assembly aborted (3 errors)! error: Assembly aborted (5 errors)!

View File

@@ -2,6 +2,10 @@ error: anon-label-bad.asm(2):
Label "!0" created outside of a SECTION Label "!0" created outside of a SECTION
error: anon-label-bad.asm(6): error: anon-label-bad.asm(6):
Reference to anonymous label 2 before, when only 1 has been created so far Reference to anonymous label 2 before, when only 1 has been created so far
error: anon-label-bad.asm(18): error: anon-label-bad.asm(9):
syntax error syntax error
error: Assembly aborted (3 errors)! error: anon-label-bad.asm(10):
syntax error
error: anon-label-bad.asm(22):
syntax error
error: Assembly aborted (5 errors)!

View File

@@ -4,12 +4,14 @@ macro def_sect
ELSE ELSE
SECTION "\1", \2, BANK[\3] SECTION "\1", \2, BANK[\3]
ENDC ENDC
Label\@::
PRINTLN BANK("\1") PRINTLN "\1 (\2): ", BANK("\1"), " == ", BANK(Label\@)
endm endm
def_sect ROM0_ok, ROM0 def_sect ROM0_ok1, ROM0
def_sect ROMX_ok, ROMX, 42 def_sect ROM0_ok2, ROM0[$2000]
def_sect ROMX_ok1, ROMX[$4567]
def_sect ROMX_ok2, ROMX, 42
def_sect ROMX_bad, ROMX def_sect ROMX_bad, ROMX
def_sect VRAM_ok, VRAM, 1 def_sect VRAM_ok, VRAM, 1
def_sect VRAM_bad, VRAM def_sect VRAM_bad, VRAM
@@ -20,3 +22,5 @@ endm
def_sect WRAMX_bad,WRAMX def_sect WRAMX_bad,WRAMX
def_sect OAM_ok, OAM def_sect OAM_ok, OAM
def_sect HRAM_ok, HRAM def_sect HRAM_ok, HRAM
PRINTLN "def_sect: ", BANK(def_sect) ; not a label

View File

@@ -1,9 +1,23 @@
error: bank.asm(13) -> bank.asm::def_sect(8): error: bank.asm(13) -> bank.asm::def_sect(8):
Expected constant expression: Section "ROMX_ok1"'s bank is not known
error: bank.asm(13) -> bank.asm::def_sect(8):
Expected constant expression: "Label_u3"'s bank is not known
error: bank.asm(15) -> bank.asm::def_sect(8):
Expected constant expression: Section "ROMX_bad"'s bank is not known Expected constant expression: Section "ROMX_bad"'s bank is not known
error: bank.asm(15) -> bank.asm::def_sect(8): error: bank.asm(15) -> bank.asm::def_sect(8):
Expected constant expression: "Label_u5"'s bank is not known
error: bank.asm(17) -> bank.asm::def_sect(8):
Expected constant expression: Section "VRAM_bad"'s bank is not known Expected constant expression: Section "VRAM_bad"'s bank is not known
error: bank.asm(17) -> bank.asm::def_sect(8): error: bank.asm(17) -> bank.asm::def_sect(8):
Expected constant expression: "Label_u7"'s bank is not known
error: bank.asm(19) -> bank.asm::def_sect(8):
Expected constant expression: Section "SRAM_bad"'s bank is not known Expected constant expression: Section "SRAM_bad"'s bank is not known
error: bank.asm(20) -> bank.asm::def_sect(8): error: bank.asm(19) -> bank.asm::def_sect(8):
Expected constant expression: "Label_u9"'s bank is not known
error: bank.asm(22) -> bank.asm::def_sect(8):
Expected constant expression: Section "WRAMX_bad"'s bank is not known Expected constant expression: Section "WRAMX_bad"'s bank is not known
error: Assembly aborted (4 errors)! error: bank.asm(22) -> bank.asm::def_sect(8):
Expected constant expression: "Label_u12"'s bank is not known
error: bank.asm(26):
BANK argument must be a label
error: Assembly aborted (11 errors)!

View File

@@ -1,12 +1,15 @@
$0 ROM0_ok1 (ROM0): $0 == $0
$2A ROM0_ok2 (ROM0[$2000]): $0 == $0
$0 ROMX_ok1 (ROMX[$4567]): $0 == $0
$1 ROMX_ok2 (ROMX): $2A == $2A
$0 ROMX_bad (ROMX): $0 == $0
$4 VRAM_ok (VRAM): $1 == $1
$0 VRAM_bad (VRAM): $0 == $0
$0 SRAM_ok (SRAM): $4 == $4
$7 SRAM_bad (SRAM): $0 == $0
$0 WRAM0_ok (WRAM0): $0 == $0
$0 WRAMX_ok (WRAMX): $7 == $7
$0 WRAMX_bad (WRAMX): $0 == $0
OAM_ok (OAM): $0 == $0
HRAM_ok (HRAM): $0 == $0
def_sect: $4B4E4142

View File

@@ -17,3 +17,23 @@ MACRO mac
ENDM ENDM
mac 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 1 mac 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 1
def nonnumeric equs "1"
def zero equ 0
def two equ 2
MACRO bad
println "nonnumeric", \<nonnumeric>
println "zero", \<zero>
println "undefined", \<undefined>
println "two", \<two>
println "2", \<2>
ENDM
bad 42
MACRO toolong
println \<abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz>
ENDM
toolong 42

View File

@@ -0,0 +1,15 @@
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(26):
Bracketed symbol "nonnumeric" is not numeric
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(27):
Invalid bracketed macro argument '\<0>'
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(28):
Bracketed symbol "undefined" does not exist
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(29):
Macro argument '\<2>' not defined
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(30):
Macro argument '\<2>' not defined
warning: bracketed-macro-args.asm(39) -> bracketed-macro-args.asm::toolong(36): [-Wlong-string]
Bracketed symbol name too long
error: bracketed-macro-args.asm(39) -> bracketed-macro-args.asm::toolong(36):
Bracketed symbol "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu" does not exist
error: Assembly aborted (6 errors)!

View File

@@ -5,3 +5,9 @@ last = D
$F0 $F0
$F0 $F0
$F0 $F0
nonnumeric
zero
undefined
two
2

View File

@@ -15,6 +15,7 @@ macro elif
invalid invalid
endr endr
warn "OK" warn "OK"
break ; not in a rept/for
rept 1 rept 1
if 1 if 1
break break

View File

@@ -2,5 +2,7 @@ warning: break.asm(9): [-Wuser]
done 5 done 5
warning: break.asm(17): [-Wuser] warning: break.asm(17): [-Wuser]
OK OK
FATAL: break.asm(18) -> break.asm::REPT~1(22): error: break.asm(18):
BREAK can only be used inside a REPT/FOR block
FATAL: break.asm(19) -> break.asm::REPT~1(23):
Ended block with 1 unterminated IF construct Ended block with 1 unterminated IF construct

View File

@@ -0,0 +1,10 @@
MACRO m
DEF S EQUS \1
println "{S}"
println \1
println "illegal character \
escape \z?"
println "invalid character \<\n>?"
println """invalid character \< >?"""
ENDM
m "(\n \r \t)"

View File

@@ -0,0 +1,7 @@
error: character-escapes.asm(10) -> character-escapes.asm::m(6):
Illegal character escape 'z'
error: character-escapes.asm(10) -> character-escapes.asm::m(7):
Invalid character in bracketed macro argument '\'
error: character-escapes.asm(10) -> character-escapes.asm::m(8):
Invalid character in bracketed macro argument '\t'
error: Assembly aborted (3 errors)!

View File

@@ -0,0 +1,7 @@
(
)
(
)
illegal character escape z?

View File

@@ -4,6 +4,10 @@ DEF s EQUS "Hello, \
world!" world!"
assert !strcmp("{s}", "Hello, world!") assert !strcmp("{s}", "Hello, world!")
/*
* block comment
*/
DEF t EQUS """Hello, DEF t EQUS """Hello,
world!""" world!"""
assert !strcmp("{t}", "Hello,\nworld!") assert !strcmp("{t}", "Hello,\nworld!")

4
test/asm/data-in-ram.asm Normal file
View File

@@ -0,0 +1,4 @@
SECTION "code", WRAM0
xor a
SECTION "data", WRAMX
db 42

5
test/asm/data-in-ram.err Normal file
View File

@@ -0,0 +1,5 @@
error: data-in-ram.asm(2):
Section 'code' cannot contain code or data (not ROM0 or ROMX)
error: data-in-ram.asm(4):
Section 'data' cannot contain code or data (not ROM0 or ROMX)
error: Assembly aborted (2 errors)!

View File

@@ -7,3 +7,4 @@ Label:
ds 60, .last - Label ; ...even if not constant ds 60, .last - Label ; ...even if not constant
.last .last
ds 11, $67, $89 ds 11, $67, $89
ds 2, !Label, ~Label

View File

@@ -1 +1 @@
****<2A><><EFBFBD><EFBFBD><EFBFBD>EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEg<45>g<EFBFBD>g<EFBFBD>g<EFBFBD>g<EFBFBD>g ****<2A><><EFBFBD><EFBFBD><EFBFBD>EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEg<45>g<EFBFBD>g<EFBFBD>g<EFBFBD>g<EFBFBD>g<01>

View File

@@ -0,0 +1 @@
ENDC

View File

@@ -0,0 +1,2 @@
FATAL: endc-outside-if.asm(1):
Found ENDC outside an IF construct

View File

@@ -0,0 +1,4 @@
SECTION "test", ROM0
LOAD "ram", WRAM0
ENDSECTION
ENDL

View File

@@ -0,0 +1,2 @@
FATAL: endsection-in-load.asm(3):
Cannot end the section within a `LOAD` block

View File

@@ -0,0 +1,4 @@
SECTION "test", WRAM0
UNION
ENDSECTION
ENDU

View File

@@ -0,0 +1,2 @@
FATAL: endsection-in-union.asm(3):
Cannot end the section within a UNION

View File

@@ -0,0 +1 @@
ENDSECTION

View File

@@ -0,0 +1,2 @@
FATAL: endsection-outside-section.asm(1):
Cannot end the section outside of a SECTION

View File

@@ -0,0 +1,2 @@
SECTION FRAGMENT "test", ROM0[0]
SECTION FRAGMENT "test", ROM0[1]

View File

@@ -0,0 +1,4 @@
error: fragment-mismatch.asm(2):
Section already declared as fixed at incompatible address $0000
FATAL: fragment-mismatch.asm(2):
Cannot create section "test" (1 error)

View File

@@ -0,0 +1 @@
SECTION "hram", HRAM, BANK[0]

View File

@@ -0,0 +1,3 @@
error: impossible-bank.asm(1):
BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections
error: Assembly aborted (1 error)!

View File

@@ -13,3 +13,8 @@ PRINTLN STRCAT("{NAME}_{d:INDEX}", " is ", {NAME}_{d:INDEX})
; Purges ITEM_100 ; Purges ITEM_100
PURGE {NAME}_{d:INDEX} PURGE {NAME}_{d:INDEX}
ASSERT !DEF({NAME}_{d:INDEX}) ASSERT !DEF({NAME}_{d:INDEX})
; not string or number
MACRO foo
ENDM
PRINTLN "foo {foo}"

View File

@@ -0,0 +1,3 @@
error: interpolation.asm(20):
Only numerical and string symbols can be interpolated
error: Assembly aborted (1 error)!

View File

@@ -1 +1,2 @@
ITEM_100 is hundredth ITEM_100 is hundredth
foo

View File

@@ -0,0 +1,23 @@
; valid
SECTION "valid", ROM0
align 16 ; this is achievable at $0000
; invalid
SECTION "invalid", ROMX[$4000]
align 16
SECTION "a", ROMX[$4000], ALIGN[20]
SECTION FRAGMENT "b", ROM0[$0000], ALIGN[20]
SECTION UNION "c", WRAM0[$c000], ALIGN[20]
; unattainable
SECTION "d", HRAM[$ff80], ALIGN[10]
SECTION FRAGMENT "e", ROMX[$4000], ALIGN[15]
SECTION UNION "f", WRAM0[$c000], ALIGN[15]

View File

@@ -0,0 +1,15 @@
error: invalid-alignment.asm(9):
Section's fixed address fails required alignment (PC = $4000)
error: invalid-alignment.asm(11):
Alignment must be between 0 and 16, not 20
error: invalid-alignment.asm(13):
Alignment must be between 0 and 16, not 20
error: invalid-alignment.asm(15):
Alignment must be between 0 and 16, not 20
error: invalid-alignment.asm(19):
Section "d"'s fixed address doesn't match its alignment
error: invalid-alignment.asm(21):
Section "e"'s fixed address doesn't match its alignment
error: invalid-alignment.asm(23):
Section "f"'s fixed address doesn't match its alignment
error: Assembly aborted (7 errors)!

View File

@@ -0,0 +1 @@
SECTION "vram", VRAM, BANK[2]

View File

@@ -0,0 +1,3 @@
error: invalid-bank.asm(1):
VRAM bank value $0002 out of range ($0000 to $0001)
error: Assembly aborted (1 error)!

View File

@@ -0,0 +1 @@
DEF S EQUS CHARSUB("ABC", 4)

View File

@@ -0,0 +1,2 @@
warning: invalid-charsub.asm(1): [-Wbuiltin-args]
CHARSUB: Position 4 is past the end of the string

View File

@@ -0,0 +1,16 @@
println STRFMT("%+d %++d", 42, 42)
println STRFMT("%#x %##x", 42, 42)
println STRFMT("%-4d %--4d", 42, 42)
println STRFMT("%.f %..f", 42.0, 42.0)
DEF N = 42
println "{5d:N} {5d5:N}"
println "{x:N} {xx:N}"
println STRFMT("%+s", "hello")
println STRFMT("%#s", "hello")
println STRFMT("%0s", "hello")
println STRFMT("%.5s", "hello")
println STRFMT("%#d", 42)
println STRFMT("%.5d", 42)

View File

@@ -0,0 +1,25 @@
error: invalid-format.asm(1):
STRFMT: Invalid format spec for argument 2
error: invalid-format.asm(2):
STRFMT: Invalid format spec for argument 2
error: invalid-format.asm(3):
STRFMT: Invalid format spec for argument 2
error: invalid-format.asm(4):
STRFMT: Invalid format spec for argument 2
error: invalid-format.asm(7):
Invalid format spec '5d5'
error: invalid-format.asm(8):
Invalid format spec 'xx'
error: invalid-format.asm(10):
Formatting string with sign flag '+'
error: invalid-format.asm(11):
Formatting string with prefix flag '#'
error: invalid-format.asm(12):
Formatting string with padding flag '0'
error: invalid-format.asm(13):
Formatting string with fractional width
error: invalid-format.asm(15):
Formatting type 'd' with prefix flag '#'
error: invalid-format.asm(16):
Formatting type 'd' with fractional width
error: Assembly aborted (12 errors)!

View File

@@ -0,0 +1,12 @@
+42 %d
$2a %x
42 %4d
42 %f
42 42
2a 2a
hello
hello
hello
hello
42
42

3
test/asm/invalid-jr.asm Normal file
View File

@@ -0,0 +1,3 @@
SECTION "test", ROM0
Label: ds 256
jr Label

3
test/asm/invalid-jr.err Normal file
View File

@@ -0,0 +1,3 @@
error: invalid-jr.asm(3):
jr target out of reach (expected -129 < -258 < 128)
error: Assembly aborted (1 error)!

6
test/asm/invalid-opt.asm Normal file
View File

@@ -0,0 +1,6 @@
opt b123
opt g12345
opt p1234
opt Q1234
opt Q32
opt W

13
test/asm/invalid-opt.err Normal file
View File

@@ -0,0 +1,13 @@
error: invalid-opt.asm(1):
Must specify exactly 2 characters for option 'b'
error: invalid-opt.asm(2):
Must specify exactly 4 characters for option 'g'
error: invalid-opt.asm(3):
Invalid argument for option 'p'
error: invalid-opt.asm(4):
Invalid argument for option 'Q'
error: invalid-opt.asm(5):
Argument for option 'Q' must be between 1 and 31
error: invalid-opt.asm(6):
Must specify an argument for option 'W'
error: Assembly aborted (6 errors)!

View File

@@ -0,0 +1,6 @@
ENDU ; outside UNION
NEXTU ; outside UNION
UNION ; outside SECTION
SECTION "test", WRAM0
UNION ; no ENDU

View File

@@ -0,0 +1,9 @@
error: invalid-union.asm(1):
Found ENDU outside of a UNION construct
error: invalid-union.asm(2):
Found NEXTU outside of a UNION construct
error: invalid-union.asm(3):
UNIONs must be inside a SECTION
error: invalid-union.asm(7):
Unterminated UNION construct
error: Assembly aborted (4 errors)!

View File

@@ -1,3 +1,10 @@
; Test text after \ line continuation
MACRO \ spam
WARN "spam"
ENDM
spam ; The macro was defined despite the error
; Test that \ after a macro invocation at the end of the file doesn't ; Test that \ after a macro invocation at the end of the file doesn't
; cause a segfault. ; cause a segfault.

View File

@@ -1,3 +1,7 @@
error: line-continuation.asm(7): error: line-continuation.asm(3):
Begun line continuation, but encountered character 's'
warning: line-continuation.asm(6) -> line-continuation.asm::spam(4): [-Wuser]
spam
error: line-continuation.asm(14):
Label "foo" created outside of a SECTION Label "foo" created outside of a SECTION
error: Assembly aborted (1 error)! error: Assembly aborted (2 errors)!

View File

@@ -0,0 +1,5 @@
SECTION "outer", ROM0
LOAD "inner", WRAM0
LOAD "matryoshka", HRAM
ENDL
ENDL

View File

@@ -0,0 +1,5 @@
error: load-in-load.asm(3):
`LOAD` blocks cannot be nested
error: load-in-load.asm(5):
Found `ENDL` outside of a `LOAD` block
error: Assembly aborted (2 errors)!

6
test/asm/negative-ds.asm Normal file
View File

@@ -0,0 +1,6 @@
SECTION "manual union", WRAM0
Foo:: dw
ds @ - Foo
Bar:: db
ds -1
Baz:: dl

2
test/asm/negative-ds.err Normal file
View File

@@ -0,0 +1,2 @@
FATAL: negative-ds.asm(5):
Constant must not be negative: -1

View File

@@ -11,3 +11,5 @@ Label:
Exported:: Exported::
PURGE Exported PURGE Exported
Exported:: Exported::
PURGE Undefined

View File

@@ -1,3 +1,5 @@
error: purge.asm(9): error: purge.asm(9):
Symbol "Referenced" is referenced and thus cannot be purged Symbol "Referenced" is referenced and thus cannot be purged
error: Assembly aborted (1 error)! error: purge.asm(15):
'Undefined' not defined
error: Assembly aborted (2 errors)!

View File

@@ -6,3 +6,9 @@ REPT 3
ENDR ENDR
WARN "Line 8" WARN "Line 8"
REPT 2
REPT 2
WARN "Line 12"
ENDR
ENDR

View File

@@ -8,3 +8,11 @@ warning: rept-line-no.asm(3) -> rept-line-no.asm::REPT~3(5): [-Wuser]
Line 5 Line 5
warning: rept-line-no.asm(8): [-Wuser] warning: rept-line-no.asm(8): [-Wuser]
Line 8 Line 8
warning: rept-line-no.asm(10) -> rept-line-no.asm::REPT~1(11) -> rept-line-no.asm::REPT~1::REPT~1(12): [-Wuser]
Line 12
warning: rept-line-no.asm(10) -> rept-line-no.asm::REPT~1(11) -> rept-line-no.asm::REPT~1::REPT~2(12): [-Wuser]
Line 12
warning: rept-line-no.asm(10) -> rept-line-no.asm::REPT~2(11) -> rept-line-no.asm::REPT~2::REPT~1(12): [-Wuser]
Line 12
warning: rept-line-no.asm(10) -> rept-line-no.asm::REPT~2(11) -> rept-line-no.asm::REPT~2::REPT~2(12): [-Wuser]
Line 12

View File

@@ -0,0 +1,4 @@
SECTION "outer", ROM0
LOAD "ram", WRAM0
SECTION "inner", ROM0
ENDL

View File

@@ -0,0 +1,2 @@
FATAL: section-in-load.asm(3):
Cannot change the section within a `LOAD` block

View File

@@ -0,0 +1,5 @@
SECTION "outer", WRAM0
UNION
SECTION "inner", WRAM0
NEXTU
ENDU

View File

@@ -0,0 +1,2 @@
FATAL: section-in-union.asm(3):
Cannot change the section within a UNION

View File

@@ -0,0 +1 @@
assert SECTION(Undefined)

View File

@@ -0,0 +1,2 @@
FATAL: section-name-undefined.asm(1):
Unknown symbol "Undefined"

View File

@@ -0,0 +1,2 @@
SECTION UNION "test", WRAM0[$c000]
SECTION UNION "test", WRAM0[$c001]

View File

@@ -0,0 +1,4 @@
error: section-union-mismatch.asm(2):
Section already declared as fixed at different address $c000
FATAL: section-union-mismatch.asm(2):
Cannot create section "test" (1 error)

View File

@@ -0,0 +1 @@
opt x ; there is no opt x

View File

@@ -0,0 +1,3 @@
error: undefined-opt.asm(1):
Unknown option 'x'
error: Assembly aborted (1 error)!

View File

@@ -0,0 +1,3 @@
SECTION "test", ROM0
UNION
ENDU

View File

@@ -0,0 +1,5 @@
error: union-in-rom.asm(2):
Cannot use UNION inside of ROM0 or ROMX sections
error: union-in-rom.asm(3):
Found ENDU outside of a UNION construct
error: Assembly aborted (2 errors)!

View File

@@ -0,0 +1,11 @@
SECTION "test", WRAM0
UNION
UNION
db
NEXTU
dw
ENDU
NEXTU
dl
ENDU
assert sizeof("test") == 4

View File

@@ -20,3 +20,14 @@ for p, 10
println "p = {d:p}" println "p = {d:p}"
endc endc
endr endr
rept 3
if def(m)
purge m
endc
MACRO m
println "go \1 \@"
ENDM
m \@
endr
m outside

View File

@@ -52,3 +52,7 @@ p = 9: _u19
q = 5 q = 5
(m: still _u23) (m: still _u23)
(p: still _u19) (p: still _u19)
go _u25 _u26
go _u27 _u28
go _u29 _u30
go outside _u31

View File

@@ -0,0 +1 @@
REPT 3

View File

@@ -0,0 +1,3 @@
error: unterminated-rept.asm(2):
Unterminated REPT/FOR block
error: Assembly aborted (1 error)!