peek(0) => peek()

This does not completely refactor `peek` as #708 suggested,
to make it shift and cache a character itself. However it
does simplify the lexer code.
This commit is contained in:
Rangi
2021-03-26 18:13:01 -04:00
committed by Eldred Habert
parent 9558ccea1b
commit eba06404f0

View File

@@ -708,8 +708,7 @@ static struct Expansion *getExpansionAtDistance(size_t *distance)
return expansion; return expansion;
} }
static void beginExpansion(size_t distance, uint8_t skip, char const *str, bool owned, static void beginExpansion(uint8_t skip, char const *str, bool owned, char const *name)
char const *name)
{ {
size_t size = strlen(str); size_t size = strlen(str);
@@ -717,7 +716,8 @@ static void beginExpansion(size_t distance, uint8_t skip, char const *str, bool
if (!size) if (!size)
return; return;
distance += lexerState->expansionOfs; /* Distance argument is relative to read offset! */ /* Distance argument is relative to read offset! */
size_t distance = lexerState->expansionOfs;
/* Increase the total length of all parents, and return the topmost one */ /* Increase the total length of all parents, and return the topmost one */
struct Expansion *parent = NULL; struct Expansion *parent = NULL;
@@ -868,19 +868,22 @@ static int peekInternal(uint8_t distance)
static void shiftChar(void); static void shiftChar(void);
static char const *readInterpolation(void); static char const *readInterpolation(void);
static int peek(uint8_t distance) static int peek(void)
{ {
int c; int c;
restart: restart:
c = peekInternal(distance); c = peekInternal(0);
if (lexerState->macroArgScanDistance > 0)
return c;
lexerState->macroArgScanDistance = 1; /* Do not consider again */
if (distance >= lexerState->macroArgScanDistance) {
lexerState->macroArgScanDistance = distance + 1; /* Do not consider again */
if (c == '\\' && !lexerState->disableMacroArgs) { if (c == '\\' && !lexerState->disableMacroArgs) {
/* If character is a backslash, check for a macro arg */ /* If character is a backslash, check for a macro arg */
lexerState->macroArgScanDistance++; lexerState->macroArgScanDistance++;
c = peekInternal(distance + 1); c = peekInternal(1);
if (isMacroChar(c)) { if (isMacroChar(c)) {
char const *str = readMacroArg(c); char const *str = readMacroArg(c);
@@ -894,7 +897,7 @@ restart:
goto restart; goto restart;
} }
beginExpansion(distance, 2, str, c == '#', NULL); beginExpansion(2, str, c == '#', NULL);
/* /*
* Assuming macro args can't be recursive (I'll be damned if a way * Assuming macro args can't be recursive (I'll be damned if a way
@@ -914,11 +917,10 @@ restart:
char const *ptr = readInterpolation(); char const *ptr = readInterpolation();
if (ptr) { if (ptr) {
beginExpansion(distance, 0, ptr, false, ptr); beginExpansion(0, ptr, false, ptr);
goto restart; goto restart;
} }
} }
}
return c; return c;
} }
@@ -930,7 +932,7 @@ static void shiftChar(void)
if (lexerState->captureSize + 1 >= lexerState->captureCapacity) if (lexerState->captureSize + 1 >= lexerState->captureCapacity)
reallocCaptureBuf(); reallocCaptureBuf();
/* TODO: improve this? */ /* TODO: improve this? */
lexerState->captureBuf[lexerState->captureSize] = peek(0); lexerState->captureBuf[lexerState->captureSize] = peek();
} }
lexerState->captureSize++; lexerState->captureSize++;
} }
@@ -994,7 +996,7 @@ nextExpansion:
static int nextChar(void) static int nextChar(void)
{ {
int c = peek(0); int c = peek();
/* If not at EOF, advance read position */ /* If not at EOF, advance read position */
if (c != EOF) if (c != EOF)
@@ -1004,7 +1006,7 @@ static int nextChar(void)
static void handleCRLF(int c) static void handleCRLF(int c)
{ {
if (c == '\r' && peek(0) == '\n') if (c == '\r' && peek() == '\n')
shiftChar(); shiftChar();
} }
@@ -1069,13 +1071,13 @@ static void discardBlockComment(void)
nextLine(); nextLine();
continue; continue;
case '/': case '/':
if (peek(0) == '*') { if (peek() == '*') {
warning(WARNING_NESTED_COMMENT, warning(WARNING_NESTED_COMMENT,
"/* in block comment\n"); "/* in block comment\n");
} }
continue; continue;
case '*': case '*':
if (peek(0) == '/') { if (peek() == '/') {
shiftChar(); shiftChar();
goto finish; goto finish;
} }
@@ -1097,7 +1099,7 @@ static void discardComment(void)
lexerState->disableMacroArgs = true; lexerState->disableMacroArgs = true;
lexerState->disableInterpolation = true; lexerState->disableInterpolation = true;
for (;;) { for (;;) {
int c = peek(0); int c = peek();
if (c == EOF || c == '\r' || c == '\n') if (c == EOF || c == '\r' || c == '\n')
break; break;
@@ -1113,7 +1115,7 @@ static void readLineContinuation(void)
{ {
dbgPrint("Beginning line continuation\n"); dbgPrint("Beginning line continuation\n");
for (;;) { for (;;) {
int c = peek(0); int c = peek();
if (isWhitespace(c)) { if (isWhitespace(c)) {
shiftChar(); shiftChar();
@@ -1144,7 +1146,7 @@ static void readAnonLabelRef(char c)
do { do {
shiftChar(); shiftChar();
n++; n++;
} while (peek(0) == c); } while (peek() == c);
sym_WriteAnonLabelName(yylval.tzSym, n, c == '-'); sym_WriteAnonLabelName(yylval.tzSym, n, c == '-');
} }
@@ -1156,7 +1158,7 @@ static void readNumber(int radix, int32_t baseValue)
uint32_t value = baseValue; uint32_t value = baseValue;
for (;; shiftChar()) { for (;; shiftChar()) {
int c = peek(0); int c = peek();
if (c == '_') if (c == '_')
continue; continue;
@@ -1176,7 +1178,7 @@ static void readFractionalPart(void)
dbgPrint("Reading fractional part\n"); dbgPrint("Reading fractional part\n");
for (;; shiftChar()) { for (;; shiftChar()) {
int c = peek(0); int c = peek();
if (c == '_') if (c == '_')
continue; continue;
@@ -1187,7 +1189,7 @@ static void readFractionalPart(void)
"Precision of fixed-point constant is too large\n"); "Precision of fixed-point constant is too large\n");
/* Discard any additional digits */ /* Discard any additional digits */
shiftChar(); shiftChar();
while (c = peek(0), (c >= '0' && c <= '9') || c == '_') while (c = peek(), (c >= '0' && c <= '9') || c == '_')
shiftChar(); shiftChar();
break; break;
} }
@@ -1214,7 +1216,7 @@ static void readBinaryNumber(void)
dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]); dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]);
for (;; shiftChar()) { for (;; shiftChar()) {
int c = peek(0); int c = peek();
int bit; int bit;
if (c == binDigits[0]) if (c == binDigits[0])
@@ -1240,7 +1242,7 @@ static void readHexNumber(void)
dbgPrint("Reading hex number\n"); dbgPrint("Reading hex number\n");
for (;; shiftChar()) { for (;; shiftChar()) {
int c = peek(0); int c = peek();
if (c >= 'a' && c <= 'f') /* Convert letters to right after digits */ if (c >= 'a' && c <= 'f') /* Convert letters to right after digits */
c = c - 'a' + 10; c = c - 'a' + 10;
@@ -1276,7 +1278,7 @@ static void readGfxConstant(void)
dbgPrint("Reading gfx constant with digits [%c,%c,%c,%c]\n", dbgPrint("Reading gfx constant with digits [%c,%c,%c,%c]\n",
gfxDigits[0], gfxDigits[1], gfxDigits[2], gfxDigits[3]); gfxDigits[0], gfxDigits[1], gfxDigits[2], gfxDigits[3]);
for (;;) { for (;;) {
int c = peek(0); int c = peek();
uint32_t pixel; uint32_t pixel;
if (c == gfxDigits[0]) if (c == gfxDigits[0])
@@ -1325,7 +1327,7 @@ static int readIdentifier(char firstChar)
size_t i; size_t i;
for (i = 1; ; i++) { for (i = 1; ; i++) {
int c = peek(0); int c = peek();
/* If that char isn't in the symbol charset, end */ /* If that char isn't in the symbol charset, end */
if ((c > '9' || c < '0') if ((c > '9' || c < '0')
@@ -1370,14 +1372,14 @@ static char const *readInterpolation(void)
struct FormatSpec fmt = fmt_NewSpec(); struct FormatSpec fmt = fmt_NewSpec();
for (;;) { for (;;) {
int c = peek(0); int c = peek();
if (c == '{') { /* Nested interpolation */ if (c == '{') { /* Nested interpolation */
shiftChar(); shiftChar();
char const *ptr = readInterpolation(); char const *ptr = readInterpolation();
if (ptr) { if (ptr) {
beginExpansion(0, 0, ptr, false, ptr); beginExpansion(0, ptr, false, ptr);
continue; /* Restart, reading from the new buffer */ continue; /* Restart, reading from the new buffer */
} }
} else if (c == EOF || c == '\r' || c == '\n' || c == '"') { } else if (c == EOF || c == '\r' || c == '\n' || c == '"') {
@@ -1483,9 +1485,9 @@ static void readString(void)
bool multiline = false; bool multiline = false;
// We reach this function after reading a single quote, but we also support triple quotes // We reach this function after reading a single quote, but we also support triple quotes
if (peek(0) == '"') { if (peek() == '"') {
shiftChar(); shiftChar();
if (peek(0) == '"') { if (peek() == '"') {
// """ begins a multi-line string // """ begins a multi-line string
shiftChar(); shiftChar();
multiline = true; multiline = true;
@@ -1496,7 +1498,7 @@ static void readString(void)
} }
for (;;) { for (;;) {
int c = peek(0); int c = peek();
// '\r', '\n' or EOF ends a single-line string early // '\r', '\n' or EOF ends a single-line string early
if (c == EOF || (!multiline && (c == '\r' || c == '\n'))) { if (c == EOF || (!multiline && (c == '\r' || c == '\n'))) {
@@ -1519,10 +1521,10 @@ static void readString(void)
case '"': case '"':
if (multiline) { if (multiline) {
// Only """ ends a multi-line string // Only """ ends a multi-line string
if (peek(0) != '"') if (peek() != '"')
break; break;
shiftChar(); shiftChar();
if (peek(0) != '"') { if (peek() != '"') {
append_yylval_tzString('"'); append_yylval_tzString('"');
break; break;
} }
@@ -1531,7 +1533,7 @@ static void readString(void)
goto finish; goto finish;
case '\\': // Character escape or macro arg case '\\': // Character escape or macro arg
c = peek(0); c = peek();
switch (c) { switch (c) {
case '\\': case '\\':
case '"': case '"':
@@ -1632,10 +1634,10 @@ static size_t appendStringLiteral(size_t i)
// We reach this function after reading a single quote, but we also support triple quotes // We reach this function after reading a single quote, but we also support triple quotes
append_yylval_tzString('"'); append_yylval_tzString('"');
if (peek(0) == '"') { if (peek() == '"') {
append_yylval_tzString('"'); append_yylval_tzString('"');
shiftChar(); shiftChar();
if (peek(0) == '"') { if (peek() == '"') {
// """ begins a multi-line string // """ begins a multi-line string
append_yylval_tzString('"'); append_yylval_tzString('"');
shiftChar(); shiftChar();
@@ -1647,7 +1649,7 @@ static size_t appendStringLiteral(size_t i)
} }
for (;;) { for (;;) {
int c = peek(0); int c = peek();
// '\r', '\n' or EOF ends a single-line string early // '\r', '\n' or EOF ends a single-line string early
if (c == EOF || (!multiline && (c == '\r' || c == '\n'))) { if (c == EOF || (!multiline && (c == '\r' || c == '\n'))) {
@@ -1670,11 +1672,11 @@ static size_t appendStringLiteral(size_t i)
case '"': case '"':
if (multiline) { if (multiline) {
// Only """ ends a multi-line string // Only """ ends a multi-line string
if (peek(0) != '"') if (peek() != '"')
break; break;
append_yylval_tzString('"'); append_yylval_tzString('"');
shiftChar(); shiftChar();
if (peek(0) != '"') if (peek() != '"')
break; break;
append_yylval_tzString('"'); append_yylval_tzString('"');
shiftChar(); shiftChar();
@@ -1683,7 +1685,7 @@ static size_t appendStringLiteral(size_t i)
goto finish; goto finish;
case '\\': // Character escape or macro arg case '\\': // Character escape or macro arg
c = peek(0); c = peek();
switch (c) { switch (c) {
// Character escape // Character escape
case '\\': case '\\':
@@ -1833,14 +1835,14 @@ static int yylex_NORMAL(void)
/* Handle ambiguous 1- or 2-char tokens */ /* Handle ambiguous 1- or 2-char tokens */
case '*': /* Either MUL or EXP */ case '*': /* Either MUL or EXP */
if (peek(0) == '*') { if (peek() == '*') {
shiftChar(); shiftChar();
return T_OP_EXP; return T_OP_EXP;
} }
return T_OP_MUL; return T_OP_MUL;
case '/': /* Either division or a block comment */ case '/': /* Either division or a block comment */
if (peek(0) == '*') { if (peek() == '*') {
shiftChar(); shiftChar();
discardBlockComment(); discardBlockComment();
break; break;
@@ -1848,21 +1850,21 @@ static int yylex_NORMAL(void)
return T_OP_DIV; return T_OP_DIV;
case '|': /* Either binary or logical OR */ case '|': /* Either binary or logical OR */
if (peek(0) == '|') { if (peek() == '|') {
shiftChar(); shiftChar();
return T_OP_LOGICOR; return T_OP_LOGICOR;
} }
return T_OP_OR; return T_OP_OR;
case '=': /* Either SET alias, or EQ */ case '=': /* Either SET alias, or EQ */
if (peek(0) == '=') { if (peek() == '=') {
shiftChar(); shiftChar();
return T_OP_LOGICEQU; return T_OP_LOGICEQU;
} }
return T_POP_EQUAL; return T_POP_EQUAL;
case '<': /* Either a LT, LTE, or left shift */ case '<': /* Either a LT, LTE, or left shift */
switch (peek(0)) { switch (peek()) {
case '=': case '=':
shiftChar(); shiftChar();
return T_OP_LOGICLE; return T_OP_LOGICLE;
@@ -1874,7 +1876,7 @@ static int yylex_NORMAL(void)
} }
case '>': /* Either a GT, GTE, or right shift */ case '>': /* Either a GT, GTE, or right shift */
switch (peek(0)) { switch (peek()) {
case '=': case '=':
shiftChar(); shiftChar();
return T_OP_LOGICGE; return T_OP_LOGICGE;
@@ -1886,7 +1888,7 @@ static int yylex_NORMAL(void)
} }
case '!': /* Either a NEQ, or negation */ case '!': /* Either a NEQ, or negation */
if (peek(0) == '=') { if (peek() == '=') {
shiftChar(); shiftChar();
return T_OP_LOGICNE; return T_OP_LOGICNE;
} }
@@ -1895,7 +1897,7 @@ static int yylex_NORMAL(void)
/* Handle colon, which may begin an anonymous label ref */ /* Handle colon, which may begin an anonymous label ref */
case ':': case ':':
c = peek(0); c = peek();
if (c != '+' && c != '-') if (c != '+' && c != '-')
return T_COLON; return T_COLON;
@@ -1910,11 +1912,11 @@ static int yylex_NORMAL(void)
/* Attempt to match `$ff00+c` */ /* Attempt to match `$ff00+c` */
if (yylval.nConstValue == 0xff00) { if (yylval.nConstValue == 0xff00) {
/* Whitespace is ignored anyways */ /* Whitespace is ignored anyways */
while (isWhitespace(c = peek(0))) while (isWhitespace(c = peek()))
shiftChar(); shiftChar();
if (c == '+') { if (c == '+') {
shiftChar(); shiftChar();
while (isWhitespace(c = peek(0))) while (isWhitespace(c = peek()))
shiftChar(); shiftChar();
if (c == 'c' || c == 'C') { if (c == 'c' || c == 'C') {
shiftChar(); shiftChar();
@@ -1937,14 +1939,14 @@ static int yylex_NORMAL(void)
case '8': case '8':
case '9': case '9':
readNumber(10, c - '0'); readNumber(10, c - '0');
if (peek(0) == '.') { if (peek() == '.') {
shiftChar(); shiftChar();
readFractionalPart(); readFractionalPart();
} }
return T_NUMBER; return T_NUMBER;
case '&': case '&':
secondChar = peek(0); secondChar = peek();
if (secondChar == '&') { if (secondChar == '&') {
shiftChar(); shiftChar();
return T_OP_LOGICAND; return T_OP_LOGICAND;
@@ -1955,7 +1957,7 @@ static int yylex_NORMAL(void)
return T_OP_AND; return T_OP_AND;
case '%': /* Either a modulo, or a binary constant */ case '%': /* Either a modulo, or a binary constant */
secondChar = peek(0); secondChar = peek();
if (secondChar != binDigits[0] && secondChar != binDigits[1]) if (secondChar != binDigits[0] && secondChar != binDigits[1])
return T_OP_MOD; return T_OP_MOD;
@@ -2016,12 +2018,12 @@ static int yylex_NORMAL(void)
if (sym && sym->type == SYM_EQUS) { if (sym && sym->type == SYM_EQUS) {
char const *s = sym_GetStringValue(sym); char const *s = sym_GetStringValue(sym);
beginExpansion(0, 0, s, false, sym->name); beginExpansion(0, s, false, sym->name);
continue; /* Restart, reading from the new buffer */ continue; /* Restart, reading from the new buffer */
} }
} }
if (tokenType == T_ID && (lexerState->atLineStart || peek(0) == ':')) if (tokenType == T_ID && (lexerState->atLineStart || peek() == ':'))
return T_LABEL; return T_LABEL;
return tokenType; return tokenType;
@@ -2047,11 +2049,11 @@ static int yylex_RAW(void)
int c; int c;
/* Trim left whitespace (stops at a block comment or line continuation) */ /* Trim left whitespace (stops at a block comment or line continuation) */
while (isWhitespace(peek(0))) while (isWhitespace(peek()))
shiftChar(); shiftChar();
for (;;) { for (;;) {
c = peek(0); c = peek();
switch (c) { switch (c) {
case '"': /* String literals inside macro args */ case '"': /* String literals inside macro args */
@@ -2061,7 +2063,7 @@ static int yylex_RAW(void)
case ';': /* Comments inside macro args */ case ';': /* Comments inside macro args */
discardComment(); discardComment();
c = peek(0); c = peek();
/* fallthrough */ /* fallthrough */
case ',': /* End of macro arg */ case ',': /* End of macro arg */
case '\r': case '\r':
@@ -2071,7 +2073,7 @@ static int yylex_RAW(void)
case '/': /* Block comments inside macro args */ case '/': /* Block comments inside macro args */
shiftChar(); shiftChar();
if (peek(0) == '*') { if (peek() == '*') {
shiftChar(); shiftChar();
discardBlockComment(); discardBlockComment();
continue; continue;
@@ -2081,7 +2083,7 @@ static int yylex_RAW(void)
case '\\': /* Character escape */ case '\\': /* Character escape */
shiftChar(); shiftChar();
c = peek(0); c = peek();
switch (c) { switch (c) {
case ',': /* Escape `\,` only inside a macro arg */ case ',': /* Escape `\,` only inside a macro arg */
@@ -2196,7 +2198,7 @@ static int skipIfBlock(bool toEndc)
int c; int c;
for (;;) { for (;;) {
c = peek(0); c = peek();
if (!isWhitespace(c)) if (!isWhitespace(c))
break; break;
shiftChar(); shiftChar();
@@ -2291,7 +2293,7 @@ static int yylex_SKIP_TO_ENDR(void)
int c; int c;
for (;;) { for (;;) {
c = peek(0); c = peek();
if (!isWhitespace(c)) if (!isWhitespace(c))
break; break;
shiftChar(); shiftChar();