Skip to content

Commit

Permalink
fbc: automatically restart fbc/parser at first executable statement i…
Browse files Browse the repository at this point in the history
…f required

- some #cmdline directive will initiate a request to restart fbc/parser
- track the stage within the parser (0=preprocessor only, 1=executable statements or preprocessor)
- show a warning on #cmdline statements if they occur after the point in parsing preprocessor only
  • Loading branch information
jayrm committed May 20, 2022
1 parent be30900 commit aff884c
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 11 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -14,6 +14,7 @@ Version 1.10.0
- sf.net #953: fbc: improve compile time error messages for LINE INPUT [#] statements giving better positional information
- sf.net #826: fbc: booleans are ranked against integer types to determine closest match in type resolution
- sf.net #455: fbc: Allow &nnn... octal literals in source (like VALINT and friends)
- fbc: automatically restart fbc/parser at first executable statement if required

[added]
- gas64: '.cif_sections' and '.cif_' directives for stack unwinding (adeyblue)
Expand Down
23 changes: 19 additions & 4 deletions src/compiler/parser-toplevel.bas
Expand Up @@ -31,6 +31,7 @@ declare sub parserLetEnd( )
'':::::
sub parserSetCtx( )

parser.stage = 0 '' start in preprocessor stage
parser.scope = FB_MAINSCOPE

parser.currproc = NULL
Expand Down Expand Up @@ -116,9 +117,16 @@ sub cProgram()
end if
#endmacro

#macro maybeRestartParser()
if( fbShouldRestart() ) then
exit sub
elseif( fbShouldContinue() = FALSE ) then
exit sub
end if
#endmacro

'' For each line...
do

'' parse the empty lines and comments and process directives, but
'' don't write to the ASM output. Clear the output buffer for
'' the current line instead of calling hEmitCurrentLineText( )
Expand All @@ -138,7 +146,7 @@ sub cProgram()
lexSkipToken( )
'' need to check for exit here because directives may have been
'' invoked or errors occur in ppCheck() calls in lexSkipToken()
maybeExitParser()
maybeRestartParser()

'' must increment statement count after EOL's
parser.stmt.cnt += 1
Expand All @@ -149,14 +157,21 @@ sub cProgram()
'' statements in the current file scope. if #include is
'' invoked, then should be handled by new include scope
if( cComment() ) then
maybeExitParser()
maybeRestartParser()
continue do
end if

maybeExitParser()
maybeRestartParser()

'' if it wasn't an empty line, comment, or directive then
'' we should expect a statement next requiring debug nodes
'' i.e. even on first entry to CProgram(), if execution makes
'' it to this point then next statement is expected to be something
'' executable. And if the parser or fbc needed to be restarted,
'' it would have happened already in maybeExitParser() above

'' set parser executable code stage
parser.stage = 1

'' line begin
astAdd( astNewDBG( AST_OP_DBG_LINEINI, lexLineNum( ), env.inf.incfile ) )
Expand Down
1 change: 1 addition & 0 deletions src/compiler/parser.bi
Expand Up @@ -174,6 +174,7 @@ type PARSERCTX
nsprefix as FBSYMCHAIN ptr '' used by cTypeOrExpression() & cIdentifier()

'' globals
stage as uinteger '' current stage (0=preprocessor, 1=executable)
scope as uinteger '' current scope (0=main module)

mangling as FB_MANGLING '' current EXTERN's mangling
Expand Down
22 changes: 15 additions & 7 deletions src/compiler/pp.bas
Expand Up @@ -10,10 +10,10 @@
#include once "pp.bi"

#define LEX_FLAGS (LEXCHECK_NOWHITESPC or _
LEXCHECK_NOSUFFIX or _
LEXCHECK_NODEFINE or _
LEXCHECK_NOQUOTES or _
LEXCHECK_NOSYMBOL)
LEXCHECK_NOSUFFIX or _
LEXCHECK_NODEFINE or _
LEXCHECK_NOQUOTES or _
LEXCHECK_NOSYMBOL)

type SYMBKWD
name as const zstring ptr
Expand Down Expand Up @@ -94,9 +94,9 @@ sub ppInit( )
end if

kwdTb(i).sym = symbAddKeyword( kwdTb(i).name, _
kwdTb(i).id, _
FB_TKCLASS_KEYWORD, _
@pp.kwdns.nspc.ns.hashtb )
kwdTb(i).id, _
FB_TKCLASS_KEYWORD, _
@pp.kwdns.nspc.ns.hashtb )
if( kwdTb(i).sym = NULL ) then
exit sub
end if
Expand Down Expand Up @@ -871,6 +871,14 @@ declare sub fbcParseArgsFromString _
private sub ppCmdline( )
dim as zstring ptr args = any

'' Prepocessor is done parsing? warn that statement is ignored
if( parser.stage > 0 ) then
errReportWarn( FB_WARNINGMSG_CMDLINEIGNORED )
'' error recovery: skip
lexSkipToken( )
exit sub
end if

if( lexGetClass( ) <> FB_TKCLASS_STRLITERAL ) then
errReport( FB_ERRMSG_SYNTAXERROR )
'' error recovery: skip
Expand Down

0 comments on commit aff884c

Please sign in to comment.