Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return a marker token at the end of any buffer #842

Merged
merged 4 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/asm/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ uint32_t lexer_GetLineNo(void);
uint32_t lexer_GetColNo(void);
void lexer_DumpStringExpansions(void);
int yylex(void);
void lexer_CaptureRept(struct CaptureBody *capture);
void lexer_CaptureMacroBody(struct CaptureBody *capture);
bool lexer_CaptureRept(struct CaptureBody *capture);
bool lexer_CaptureMacroBody(struct CaptureBody *capture);

#define INITIAL_DS_ARG_SIZE 2
struct DsArgList {
Expand Down
40 changes: 22 additions & 18 deletions src/asm/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ struct LexerState {
uint32_t colNo;
int lastToken;
int nextToken;
bool isAtEOF;
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved

struct IfStack *ifStack;

Expand All @@ -378,6 +379,7 @@ static void initState(struct LexerState *state)
state->atLineStart = true; /* yylex() will init colNo due to this */
state->lastToken = T_EOF;
state->nextToken = 0;
state->isAtEOF = false;

state->ifStack = NULL;

Expand Down Expand Up @@ -2267,11 +2269,13 @@ static int yylex_SKIP_TO_ENDR(void)

int yylex(void)
{
restart:
if (lexerState->atLineStart && lexerStateEOL) {
if (lexerStateEOL) {
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
lexer_SetState(lexerStateEOL);
lexerStateEOL = NULL;
}
/* `lexer_SetState` updates `lexerState`, so check for EOF after it */
if (lexerState->isAtEOF)
return T_EOF;
if (lexerState->atLineStart) {
/* Newlines read within an expansion should not increase the line count */
if (!lexerState->expansions)
Expand All @@ -2288,23 +2292,19 @@ int yylex(void)
int token = lexerModeFuncs[lexerState->mode]();

if (token == T_EOF) {
if (lexerState->lastToken != T_NEWLINE) {
dbgPrint("Forcing EOL at EOF\n");
token = T_NEWLINE;
} else {
/* Try to switch to new buffer; if it succeeds, scan again */
dbgPrint("Reached EOF!\n");
/* Captures end at their buffer's boundary no matter what */
if (!lexerState->capturing) {
if (!yywrap())
goto restart;
/* Try to switch to new buffer; if it succeeds, scan again */
dbgPrint("Reached EOB!\n");
/* Captures end at their buffer's boundary no matter what */
if (!lexerState->capturing) {
if (yywrap()) {
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
dbgPrint("Reached end of input.\n");
return T_EOF;
lexerState->isAtEOF = true;
}
token = T_EOB;
}
}
lexerState->lastToken = token;
lexerState->atLineStart = token == T_NEWLINE;
lexerState->atLineStart = token == T_NEWLINE || token == T_EOB;

return token;
}
Expand All @@ -2325,11 +2325,12 @@ static char *startCapture(void)
}
}

void lexer_CaptureRept(struct CaptureBody *capture)
bool lexer_CaptureRept(struct CaptureBody *capture)
{
capture->lineNo = lexer_GetLineNo();

char *captureStart = startCapture();
bool terminated = false;
unsigned int level = 0;
int c;

Expand Down Expand Up @@ -2361,7 +2362,7 @@ void lexer_CaptureRept(struct CaptureBody *capture)
* We know we have read exactly "ENDR", not e.g. an EQUS
*/
lexerState->captureSize -= strlen("ENDR");
lexerState->lastToken = T_POP_ENDR; // Force EOL at EOF
terminated = true;
goto finish;
}
level--;
Expand Down Expand Up @@ -2389,13 +2390,15 @@ void lexer_CaptureRept(struct CaptureBody *capture)
lexerState->disableMacroArgs = false;
lexerState->disableInterpolation = false;
lexerState->atLineStart = false;
return terminated;
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
}

void lexer_CaptureMacroBody(struct CaptureBody *capture)
bool lexer_CaptureMacroBody(struct CaptureBody *capture)
{
capture->lineNo = lexer_GetLineNo();

char *captureStart = startCapture();
bool terminated = false;
int c;

/* If the file is `mmap`ed, we need not to unmap it to keep access to the macro */
Expand Down Expand Up @@ -2423,7 +2426,7 @@ void lexer_CaptureMacroBody(struct CaptureBody *capture)
* We know we have read exactly "ENDM", not e.g. an EQUS
*/
lexerState->captureSize -= strlen("ENDM");
lexerState->lastToken = T_POP_ENDM; // Force EOL at EOF
terminated = true;
goto finish;
}
}
Expand All @@ -2449,4 +2452,5 @@ void lexer_CaptureMacroBody(struct CaptureBody *capture)
lexerState->disableMacroArgs = false;
lexerState->disableInterpolation = false;
lexerState->atLineStart = false;
return terminated;
}
56 changes: 32 additions & 24 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ enum {
int32_t step;
} forArgs;
struct StrFmtArgList strfmtArgs;
bool captureTerminated;
}

%type <expr> relocexpr
Expand Down Expand Up @@ -638,6 +639,7 @@ enum {
%type <expr> op_mem_ind
%type <assertType> assert_type

%token T_EOB "end of buffer"
%token T_EOF 0 "end of file"
%start asmfile

Expand All @@ -646,24 +648,23 @@ enum {
asmfile : lines
;

/*
* The lexer adds T_NEWLINE at the end of the file if one was not
* already present, so we can rely on it to end a line.
*/
lines : %empty
| lines line
;

endofline : T_NEWLINE | T_EOB
;

plain_directive : label
| label cpu_command
| label macro
| label directive
| assignment_directive
;

line : plain_directive T_NEWLINE
line : plain_directive endofline
| line_directive /* Directives that manage newlines themselves */
| error T_NEWLINE { /* Continue parsing the next line on a syntax error */
| error endofline { /* Continue parsing the next line on a syntax error */
fstk_StopRept();
}
;
Expand All @@ -678,6 +679,7 @@ line_directive : macrodef
| rept
| for
| break
| include
| if
/* It's important that all of these require being at line start for `skipIfBlock` */
| elif
Expand Down Expand Up @@ -799,8 +801,7 @@ assignment_directive : equ
| equs
;

directive : include
| endc
directive : endc
| print
| println
| printf
Expand Down Expand Up @@ -979,9 +980,11 @@ load : T_POP_LOAD sectmod string T_COMMA sectiontype sectorg sectattrs {
;

rept : T_POP_REPT uconst T_NEWLINE {
lexer_CaptureRept(&captureBody);
} T_NEWLINE {
fstk_RunRept($2, captureBody.lineNo, captureBody.body, captureBody.size);
$<captureTerminated>$ = lexer_CaptureRept(&captureBody);
} endofline {
if ($<captureTerminated>4)
fstk_RunRept($2, captureBody.lineNo, captureBody.body,
captureBody.size);
}
;

Expand All @@ -990,10 +993,11 @@ for : T_POP_FOR {
} T_ID {
lexer_ToggleStringExpansion(true);
} T_COMMA for_args T_NEWLINE {
lexer_CaptureRept(&captureBody);
} T_NEWLINE {
fstk_RunFor($3, $6.start, $6.stop, $6.step, captureBody.lineNo,
captureBody.body, captureBody.size);
$<captureTerminated>$ = lexer_CaptureRept(&captureBody);
} endofline {
if ($<captureTerminated>8)
fstk_RunFor($3, $6.start, $6.stop, $6.step, captureBody.lineNo,
captureBody.body, captureBody.size);
}

for_args : const {
Expand All @@ -1013,7 +1017,7 @@ for_args : const {
}
;

break : T_POP_BREAK T_NEWLINE {
break : label T_POP_BREAK endofline {
if (fstk_Break())
lexer_SetMode(LEXER_SKIP_TO_ENDR);
}
Expand All @@ -1024,14 +1028,18 @@ macrodef : T_POP_MACRO {
} T_ID {
lexer_ToggleStringExpansion(true);
} T_NEWLINE {
lexer_CaptureMacroBody(&captureBody);
} T_NEWLINE {
sym_AddMacro($3, captureBody.lineNo, captureBody.body, captureBody.size);
$<captureTerminated>$ = lexer_CaptureMacroBody(&captureBody);
} endofline {
if ($<captureTerminated>6)
sym_AddMacro($3, captureBody.lineNo, captureBody.body,
captureBody.size);
}
| T_LABEL T_COLON T_POP_MACRO T_NEWLINE {
lexer_CaptureMacroBody(&captureBody);
} T_NEWLINE {
sym_AddMacro($1, captureBody.lineNo, captureBody.body, captureBody.size);
$<captureTerminated>$ = lexer_CaptureMacroBody(&captureBody);
} endofline {
if ($<captureTerminated>5)
sym_AddMacro($1, captureBody.lineNo, captureBody.body,
captureBody.size);
}
;

Expand Down Expand Up @@ -1154,8 +1162,8 @@ export_list : export_list_entry
export_list_entry : scoped_id { sym_Export($1); }
;

include : T_POP_INCLUDE string {
fstk_RunInclude($2);
include : label T_POP_INCLUDE string endofline {
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
fstk_RunInclude($3);
if (failedOnMissingInclude)
YYACCEPT;
}
Expand Down
2 changes: 1 addition & 1 deletion test/asm/block-comment-termination-error.err
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ERROR: block-comment-termination-error.asm(1):
Unterminated block comment
ERROR: block-comment-termination-error.asm(1):
syntax error, unexpected newline
syntax error, unexpected end of buffer
error: Assembly aborted (2 errors)!
8 changes: 4 additions & 4 deletions test/asm/code-after-endm-endr-endc.err
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
ERROR: code-after-endm-endr-endc.asm(6):
syntax error, unexpected PRINTLN, expecting newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
ERROR: code-after-endm-endr-endc.asm(7):
Macro "mac" not defined
ERROR: code-after-endm-endr-endc.asm(12):
syntax error, unexpected PRINTLN, expecting newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
ERROR: code-after-endm-endr-endc.asm(17):
syntax error, unexpected PRINTLN, expecting newline
ERROR: code-after-endm-endr-endc.asm(19):
syntax error, unexpected PRINTLN, expecting newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
ERROR: code-after-endm-endr-endc.asm(23):
syntax error, unexpected PRINTLN, expecting newline
ERROR: code-after-endm-endr-endc.asm(25):
syntax error, unexpected PRINTLN, expecting newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
error: Assembly aborted (7 errors)!
2 changes: 1 addition & 1 deletion test/asm/nested-macrodef.err
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ warning: nested-macrodef.asm(26) -> nested-macrodef.asm::outer(22): [-Wuser]
ERROR: nested-macrodef.asm(26) -> nested-macrodef.asm::outer(24):
Unterminated macro definition
ERROR: nested-macrodef.asm(27):
syntax error, unexpected identifier, expecting newline
Macro "inner" not defined
error: Assembly aborted (2 errors)!