mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Implement opt b and opt g
This commit is contained in:
@@ -30,6 +30,19 @@ static inline void lexer_SetStateAtEOL(struct LexerState *state)
|
|||||||
lexerStateEOL = state;
|
lexerStateEOL = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern char const *binDigits;
|
||||||
|
extern char const *gfxDigits;
|
||||||
|
|
||||||
|
static inline void lexer_SetBinDigits(char const *digits)
|
||||||
|
{
|
||||||
|
binDigits = digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lexer_SetGfxDigits(char const *digits)
|
||||||
|
{
|
||||||
|
gfxDigits = digits;
|
||||||
|
}
|
||||||
|
|
||||||
struct LexerState *lexer_OpenFile(char const *path);
|
struct LexerState *lexer_OpenFile(char const *path);
|
||||||
struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo);
|
struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo);
|
||||||
void lexer_RestartRept(uint32_t lineNo);
|
void lexer_RestartRept(uint32_t lineNo);
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ char const *fstk_GetFileName(void)
|
|||||||
int nbChars = snprintf(dest, remainingChars, __VA_ARGS__); \
|
int nbChars = snprintf(dest, remainingChars, __VA_ARGS__); \
|
||||||
\
|
\
|
||||||
if (nbChars >= remainingChars) \
|
if (nbChars >= remainingChars) \
|
||||||
fatalerror("File stack entry too large"); \
|
fatalerror("File stack entry too large\n"); \
|
||||||
remainingChars -= nbChars; \
|
remainingChars -= nbChars; \
|
||||||
dest += nbChars; \
|
dest += nbChars; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|||||||
@@ -966,20 +966,26 @@ static void readFractionalPart(void)
|
|||||||
yylval.nConstValue |= fractional * (yylval.nConstValue >= 0 ? 1 : -1);
|
yylval.nConstValue |= fractional * (yylval.nConstValue >= 0 ? 1 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *binDigits;
|
||||||
|
|
||||||
static void readBinaryNumber(void)
|
static void readBinaryNumber(void)
|
||||||
{
|
{
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
|
|
||||||
dbgPrint("Reading binary number\n");
|
dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
int bit;
|
||||||
|
|
||||||
/* TODO: handle `-b`'s dynamic chars */
|
if (c == binDigits[0])
|
||||||
if (c != '0' && c != '1')
|
bit = 0;
|
||||||
|
else if (c == binDigits[1])
|
||||||
|
bit = 1;
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
if (value > (UINT32_MAX - (c - '0')) / 2)
|
if (value > (UINT32_MAX - bit) / 2)
|
||||||
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n");
|
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n");
|
||||||
value = value * 2 + (c - '0');
|
value = value * 2 + bit;
|
||||||
|
|
||||||
shiftChars(1);
|
shiftChars(1);
|
||||||
}
|
}
|
||||||
@@ -1019,19 +1025,29 @@ static void readHexNumber(void)
|
|||||||
yylval.nConstValue = value;
|
yylval.nConstValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *gfxDigits;
|
||||||
|
|
||||||
static void readGfxConstant(void)
|
static void readGfxConstant(void)
|
||||||
{
|
{
|
||||||
uint32_t bp0 = 0, bp1 = 0;
|
uint32_t bp0 = 0, bp1 = 0;
|
||||||
uint8_t width = 0;
|
uint8_t width = 0;
|
||||||
|
|
||||||
dbgPrint("Reading gfx constant\n");
|
dbgPrint("Reading gfx constant with digits [%c,%c,%c,%c]\n",
|
||||||
|
gfxDigits[0], gfxDigits[1], gfxDigits[2], gfxDigits[3]);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
uint32_t pixel;
|
||||||
|
|
||||||
/* TODO: handle `-g`'s dynamic chars */
|
if (c == gfxDigits[0])
|
||||||
if (c < '0' || c > '3')
|
pixel = 0;
|
||||||
|
else if (c == gfxDigits[1])
|
||||||
|
pixel = 1;
|
||||||
|
else if (c == gfxDigits[2])
|
||||||
|
pixel = 2;
|
||||||
|
else if (c == gfxDigits[3])
|
||||||
|
pixel = 3;
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
uint8_t pixel = c - '0';
|
|
||||||
|
|
||||||
if (width < 8) {
|
if (width < 8) {
|
||||||
bp0 = bp0 << 1 | (pixel & 1);
|
bp0 = bp0 << 1 | (pixel & 1);
|
||||||
@@ -1531,7 +1547,7 @@ static int yylex_NORMAL(void)
|
|||||||
|
|
||||||
case '%': /* Either a modulo, or a binary constant */
|
case '%': /* Either a modulo, or a binary constant */
|
||||||
secondChar = peek(0);
|
secondChar = peek(0);
|
||||||
if (secondChar != '0' && secondChar != '1')
|
if (secondChar != binDigits[0] && secondChar != binDigits[1])
|
||||||
return T_OP_MOD;
|
return T_OP_MOD;
|
||||||
|
|
||||||
yylval.nConstValue = 0;
|
yylval.nConstValue = 0;
|
||||||
|
|||||||
@@ -71,10 +71,11 @@ struct sOptionStackEntry {
|
|||||||
|
|
||||||
struct sOptionStackEntry *pOptionStack;
|
struct sOptionStackEntry *pOptionStack;
|
||||||
|
|
||||||
void opt_SetCurrentOptions(struct sOptions *pOpt)
|
void opt_SetCurrentOptions(struct sOptions *opt)
|
||||||
{
|
{
|
||||||
/* TODO */
|
CurrentOptions = *opt;
|
||||||
(void)pOpt;
|
lexer_SetGfxDigits(CurrentOptions.gbgfx);
|
||||||
|
lexer_SetBinDigits(CurrentOptions.binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_Parse(char *s)
|
void opt_Parse(char *s)
|
||||||
|
|||||||
2
test/asm/opt-b.asm
Normal file
2
test/asm/opt-b.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
OPT b.X
|
||||||
|
PRINTV %..X.X.X.
|
||||||
0
test/asm/opt-b.err
Normal file
0
test/asm/opt-b.err
Normal file
1
test/asm/opt-b.out
Normal file
1
test/asm/opt-b.out
Normal file
@@ -0,0 +1 @@
|
|||||||
|
$2A
|
||||||
2
test/asm/opt-g.asm
Normal file
2
test/asm/opt-g.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
OPT g.x0X
|
||||||
|
PRINTV `.x.x0X0X
|
||||||
0
test/asm/opt-g.err
Normal file
0
test/asm/opt-g.err
Normal file
1
test/asm/opt-g.out
Normal file
1
test/asm/opt-g.out
Normal file
@@ -0,0 +1 @@
|
|||||||
|
$F55
|
||||||
Reference in New Issue
Block a user