Implement ENDSECTION (#1211)

This commit is contained in:
Rangi
2023-11-04 18:41:17 -04:00
committed by GitHub
parent 99727cbe99
commit 259ec58140
12 changed files with 44 additions and 9 deletions

View File

@@ -258,7 +258,7 @@ size_t charmap_ConvertNext(char const **input, uint8_t **output)
*input);
if (codepointLen == 0)
error("Input string is not valid UTF-8!\n");
error("Input string is not valid UTF-8\n");
// OK because UTF-8 has no NUL in multi-byte chars
*input += codepointLen;

View File

@@ -569,7 +569,7 @@ void fstk_Init(char const *mainPath, size_t maxDepth)
struct LexerState *state = lexer_OpenFile(mainPath);
if (!state)
fatalerror("Failed to open main file!\n");
fatalerror("Failed to open main file\n");
lexer_SetState(state);
char const *fileName = lexer_GetFileName();
size_t len = strlen(fileName);

View File

@@ -217,6 +217,7 @@ static struct KeywordMapping {
{"DW", T_POP_DW},
{"DL", T_POP_DL},
{"SECTION", T_POP_SECTION},
{"ENDSECTION", T_POP_ENDSECTION},
{"PURGE", T_POP_PURGE},
{"RSRESET", T_POP_RSRESET},
@@ -572,7 +573,7 @@ struct KeywordDictNode {
uint16_t children[0x60 - ' '];
struct KeywordMapping const *keyword;
// Since the keyword structure is invariant, the min number of nodes is known at compile time
} keywordDict[370] = {0}; // Make sure to keep this correct when adding keywords!
} keywordDict[377] = {0}; // Make sure to keep this correct when adding keywords!
// Convert a char into its index into the dict
static uint8_t dictIndex(char c)

View File

@@ -632,6 +632,7 @@ enum {
%token T_POP_EXPORT "EXPORT"
%token T_POP_DB "DB" T_POP_DS "DS" T_POP_DW "DW" T_POP_DL "DL"
%token T_POP_SECTION "SECTION" T_POP_FRAGMENT "FRAGMENT"
%token T_POP_ENDSECTION "ENDSECTION"
%token T_POP_RB "RB" T_POP_RW "RW" // There is no T_POP_RL, only T_Z80_RL
%token T_POP_MACRO "MACRO"
%token T_POP_ENDM "ENDM"
@@ -936,6 +937,7 @@ directive : endc
| purge
| pops
| pushs
| endsection
| popo
| pusho
| opt
@@ -1056,6 +1058,9 @@ pops : T_POP_POPS { sect_PopSection(); }
pushs : T_POP_PUSHS { sect_PushSection(); }
;
endsection : T_POP_ENDSECTION { sect_EndSection(); }
;
fail : T_POP_FAIL string { fatalerror("%s\n", $2); }
;

View File

@@ -598,7 +598,7 @@ void sect_EndUnion(void)
void sect_CheckUnionClosed(void)
{
if (unionStack)
error("Unterminated UNION construct!\n");
error("Unterminated UNION construct\n");
}
// Output an absolute byte
@@ -965,7 +965,7 @@ void sect_PopSection(void)
fatalerror("No entries in the section stack\n");
if (currentLoadSection)
fatalerror("Cannot change the section within a `LOAD` block!\n");
fatalerror("Cannot change the section within a `LOAD` block\n");
struct SectionStackEntry *entry = sectionStack;
@@ -981,6 +981,22 @@ void sect_PopSection(void)
free(entry);
}
void sect_EndSection(void)
{
if (!currentSection)
fatalerror("Cannot end the section outside of a SECTION\n");
if (currentLoadSection)
fatalerror("Cannot end the section within a `LOAD` block\n");
if (unionStack)
fatalerror("Cannot end the section within a UNION\n");
// Reset the section scope
currentSection = NULL;
sym_SetCurrentSymbolScope(NULL);
}
bool sect_IsSizeKnown(struct Section const NONNULL(sect))
{
// SECTION UNION and SECTION FRAGMENT can still grow