Skip to content

Commit

Permalink
Implement [[ inline code blocks ]]
Browse files Browse the repository at this point in the history
Fixes gbdev#500
  • Loading branch information
Rangi42 committed Jan 24, 2021
1 parent 6623b1d commit 18205c7
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/asm/section.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void out_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
struct SectionSpec const *attributes);
void out_EndLoadSection(void);

struct Section *sect_GetCurrentSection(void);
struct Section *sect_GetSymbolSection(void);
uint32_t sect_GetSymbolOffset(void);
uint32_t sect_GetOutputOffset(void);
Expand Down
16 changes: 12 additions & 4 deletions src/asm/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1650,10 +1650,6 @@ static int yylex_NORMAL(void)
yylval.tzSym[1] = '\0';
return T_ID;

case '[':
return T_LBRACK;
case ']':
return T_RBRACK;
case '(':
return T_LPAREN;
case ')':
Expand All @@ -1663,6 +1659,18 @@ static int yylex_NORMAL(void)

/* Handle ambiguous 1- or 2-char tokens */

case '[': /* Either [ or [[ */
if (peek(0) == '[') {
shiftChars(1);
return T_2LBRACK;
}
return T_LBRACK;
case ']': /* Either ] or ]] */
if (peek(0) == ']') {
shiftChars(1);
return T_2RBRACK;
}
return T_RBRACK;
case '*': /* Either MUL or EXP */
if (peek(0) == '*') {
shiftChars(1);
Expand Down
45 changes: 43 additions & 2 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int32_t nPCOffset; /* Read by rpn_Symbol */
static uint32_t nListCountEmpty;
static bool executeElseBlock; /* If this is set, ELIFs cannot be executed anymore */
static struct CaptureBody captureBody; /* Captures a REPT/FOR or MACRO */
static uint32_t inlineBlockID = 0; /* Incrementing unique ID for inline block labels */

static void upperstring(char *dest, char const *src)
{
Expand Down Expand Up @@ -406,6 +407,12 @@ enum {
int32_t step;
} forArgs;
struct StrFmtArgList strfmtArgs;
struct {
int32_t nPCOffset;
uint32_t nListCountEmpty;
struct Section *sect;
char name[24]; // space for "inline_block$4294967295" + '\0'
} inlineBlock;
}

%type <sVal> relocexpr
Expand All @@ -429,12 +436,15 @@ enum {
%type <nConstValue> sectorg
%type <sectSpec> sectattrs

%type <inlineBlock> inline_block

%token <nConstValue> T_NUMBER "number"
%token <tzString> T_STRING "string"

%token T_COMMA ","
%token T_COLON ":"
%token T_LBRACK "[" T_RBRACK "]"
%token T_2LBRACK "[[" T_2RBRACK "]]"
%token T_LPAREN "(" T_RPAREN ")"
%token T_NEWLINE "newline"

Expand Down Expand Up @@ -1179,22 +1189,53 @@ reloc_8bit_no_str : relocexpr_no_str {
}
;

reloc_16bit : relocexpr {
reloc_16bit : inline_block { rpn_Symbol(&$$, $1.name); }
| relocexpr {
if (rpn_isKnown(&$1)
&& ($1.nVal < -32768 || $1.nVal > 65535))
warning(WARNING_TRUNCATION, "Expression must be 16-bit\n");
$$ = $1;
}
;

reloc_16bit_no_str : relocexpr_no_str {
reloc_16bit_no_str : inline_block { rpn_Symbol(&$$, $1.name); }
| relocexpr_no_str {
if (rpn_isKnown(&$1)
&& ($1.nVal < -32768 || $1.nVal > 65535))
warning(WARNING_TRUNCATION, "Expression must be 16-bit\n");
$$ = $1;
}
;

inline_block : T_2LBRACK T_NEWLINE {
struct Section *sect = sect_GetCurrentSection();
struct SectionSpec attrs;

attrs.bank = sect->bank == 0 ? -1 : sect->bank; // BANK[0] not allowed
attrs.alignment = sect->align;
attrs.alignOfs = sect->alignOfs;
sect->modifier = SECTION_FRAGMENT;
$<inlineBlock>$.nPCOffset = nPCOffset;
$<inlineBlock>$.nListCountEmpty = nListCountEmpty;
out_PushSection();
sprintf($<inlineBlock>$.name, "inline_block$%" PRIu32, inlineBlockID++);
out_NewSection($<inlineBlock>$.name, sect->type, sect->org, &attrs, sect->modifier);
sym_AddLabel($<inlineBlock>$.name);
$<inlineBlock>$.sect = sect_GetCurrentSection();
} lines T_2RBRACK {
out_PopSection();
struct Section *sect = sect_GetCurrentSection();

free($<inlineBlock>3.sect->name);
$<inlineBlock>3.sect->name = strdup(sect->name);
if ($<inlineBlock>3.sect->name == NULL)
fatalerror("Not enough memory for section name: %s\n", strerror(errno));
nPCOffset = $<inlineBlock>3.nPCOffset;
nListCountEmpty = $<inlineBlock>3.nListCountEmpty;
$$.sect = $<inlineBlock>3.sect;
strcpy($$.name, $<inlineBlock>3.name);
}
;

relocexpr : relocexpr_no_str
| string {
Expand Down
5 changes: 5 additions & 0 deletions src/asm/section.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,11 @@ void out_EndLoadSection(void)
loadOffset = 0;
}

struct Section *sect_GetCurrentSection(void)
{
return pCurrentSection;
}

struct Section *sect_GetSymbolSection(void)
{
return currentLoadSection ? currentLoadSection : pCurrentSection;
Expand Down

0 comments on commit 18205c7

Please sign in to comment.