ref: ece6853e0f5d206d5b2159aa300ce2a81030d130
parent: b7b03ee4510f1dd3f8b7dfdbe4a21d5c0d9bfeb2
author: ISSOtm <[email protected]>
date: Tue Aug 18 09:05:55 EDT 2020
Implement `opt b` and `opt g`
--- a/include/asm/lexer.h
+++ b/include/asm/lexer.h
@@ -30,6 +30,19 @@
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_OpenFileView(char *buf, size_t size, uint32_t lineNo);
void lexer_RestartRept(uint32_t lineNo);
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -336,7 +336,7 @@
int nbChars = snprintf(dest, remainingChars, __VA_ARGS__); \
\
if (nbChars >= remainingChars) \
- fatalerror("File stack entry too large"); \
+ fatalerror("File stack entry too large\n"); \
remainingChars -= nbChars; \
dest += nbChars; \
} while (0)
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -966,20 +966,26 @@
yylval.nConstValue |= fractional * (yylval.nConstValue >= 0 ? 1 : -1);
}
+char const *binDigits;
+
static void readBinaryNumber(void)
{
uint32_t value = 0;
- dbgPrint("Reading binary number\n");
+ dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]);
for (;;) {
int c = peek(0);
+ int bit;
- /* TODO: handle `-b`'s dynamic chars */
- if (c != '0' && c != '1')
+ if (c == binDigits[0])
+ bit = 0;
+ else if (c == binDigits[1])
+ bit = 1;
+ else
break;
- if (value > (UINT32_MAX - (c - '0')) / 2)
+ if (value > (UINT32_MAX - bit) / 2)
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n");
- value = value * 2 + (c - '0');
+ value = value * 2 + bit;
shiftChars(1);
}
@@ -1019,19 +1025,29 @@
yylval.nConstValue = value;
}
+char const *gfxDigits;
+
static void readGfxConstant(void)
{
uint32_t bp0 = 0, bp1 = 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 (;;) {
int c = peek(0);
+ uint32_t pixel;
- /* TODO: handle `-g`'s dynamic chars */
- if (c < '0' || c > '3')
+ if (c == gfxDigits[0])
+ 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;
- uint8_t pixel = c - '0';
if (width < 8) {
bp0 = bp0 << 1 | (pixel & 1);
@@ -1531,7 +1547,7 @@
case '%': /* Either a modulo, or a binary constant */
secondChar = peek(0);
- if (secondChar != '0' && secondChar != '1')
+ if (secondChar != binDigits[0] && secondChar != binDigits[1])
return T_OP_MOD;
yylval.nConstValue = 0;
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -71,10 +71,11 @@
struct sOptionStackEntry *pOptionStack;
-void opt_SetCurrentOptions(struct sOptions *pOpt)
+void opt_SetCurrentOptions(struct sOptions *opt)
{
- /* TODO */
- (void)pOpt;
+ CurrentOptions = *opt;
+ lexer_SetGfxDigits(CurrentOptions.gbgfx);
+ lexer_SetBinDigits(CurrentOptions.binary);
}
void opt_Parse(char *s)
--- /dev/null
+++ b/test/asm/opt-b.asm
@@ -1,0 +1,2 @@
+OPT b.X
+PRINTV %..X.X.X.
--- /dev/null
+++ b/test/asm/opt-b.out
@@ -1,0 +1,1 @@
+$2A
\ No newline at end of file
--- /dev/null
+++ b/test/asm/opt-g.asm
@@ -1,0 +1,2 @@
+OPT g.x0X
+PRINTV `.x.x0X0X
--- /dev/null
+++ b/test/asm/opt-g.out
@@ -1,0 +1,1 @@
+$F55
\ No newline at end of file