mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 18:52:07 +00:00
Added ELIF
In addition, make some formatting changes, and add some extra error handling (for when ELIF, ELSE, or ENDC are encountered without a corresponding IF).
This commit is contained in:
@@ -23,6 +23,7 @@ extern ULONG nTotalLines;
|
|||||||
extern ULONG nPC;
|
extern ULONG nPC;
|
||||||
extern ULONG nPass;
|
extern ULONG nPass;
|
||||||
extern ULONG nIFDepth;
|
extern ULONG nIFDepth;
|
||||||
|
extern bool skipElif;
|
||||||
extern char tzCurrentFileName[_MAX_PATH + 1];
|
extern char tzCurrentFileName[_MAX_PATH + 1];
|
||||||
extern struct Section *pCurrentSection;
|
extern struct Section *pCurrentSection;
|
||||||
extern struct sSymbol *tHashedSymbols[HASHSIZE];
|
extern struct sSymbol *tHashedSymbols[HASHSIZE];
|
||||||
|
|||||||
256
src/asm/asmy.y
256
src/asm/asmy.y
@@ -289,70 +289,75 @@ void copymacro( void )
|
|||||||
yyskipbytes( ulNewMacroSize+4 );
|
yyskipbytes( ulNewMacroSize+4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG isIf( char *s )
|
ULONG isIf(char *s)
|
||||||
{
|
{
|
||||||
return( (strncasecmp(s,"If",2)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[2]) );
|
return((strncasecmp(s,"If",2) == 0) && isWhiteSpace(s[-1]) && isWhiteSpace(s[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG isElse( char *s )
|
ULONG isElif(char *s)
|
||||||
{
|
{
|
||||||
return( (strncasecmp(s,"Else",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
|
return((strncasecmp(s,"Elif",4) == 0) && isWhiteSpace(s[-1]) && isWhiteSpace(s[4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG isEndc( char *s )
|
ULONG isElse(char *s)
|
||||||
{
|
{
|
||||||
return( (strncasecmp(s,"Endc",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
|
return((strncasecmp(s,"Else",4) == 0) && isWhiteSpace(s[-1]) && isWhiteSpace(s[4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void if_skip_to_else( void )
|
ULONG isEndc(char *s)
|
||||||
{
|
{
|
||||||
SLONG level=1, len, instring=0;
|
return((strncasecmp(s,"Endc",4) == 0) && isWhiteSpace(s[-1]) && isWhiteSpace(s[4]));
|
||||||
char *src=pCurrentBuffer->pBuffer;
|
}
|
||||||
|
|
||||||
while( *src && level )
|
void if_skip_to_else()
|
||||||
{
|
{
|
||||||
if( *src=='\n' )
|
SLONG level = 1;
|
||||||
nLineNo+=1;
|
bool inString = false;
|
||||||
|
char *src=pCurrentBuffer->pBuffer;
|
||||||
|
|
||||||
if( instring==0 )
|
while (*src && level) {
|
||||||
{
|
if (*src == '\n') {
|
||||||
if( isIf(src) )
|
nLineNo++;
|
||||||
{
|
|
||||||
level+=1;
|
|
||||||
src+=2;
|
|
||||||
}
|
|
||||||
else if( level==1 && isElse(src) )
|
|
||||||
{
|
|
||||||
level-=1;
|
|
||||||
src+=4;
|
|
||||||
}
|
|
||||||
else if( isEndc(src) )
|
|
||||||
{
|
|
||||||
level-=1;
|
|
||||||
if( level!=0 )
|
|
||||||
src+=4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( *src=='\"' )
|
|
||||||
instring=1;
|
|
||||||
src+=1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (!inString) {
|
||||||
if( *src=='\\' )
|
if (isIf(src)) {
|
||||||
{
|
level++;
|
||||||
src+=2;
|
src += 2;
|
||||||
|
|
||||||
|
} else if (level == 1 && isElif(src)) {
|
||||||
|
level--;
|
||||||
|
skipElif = false;
|
||||||
|
|
||||||
|
} else if (level == 1 && isElse(src)) {
|
||||||
|
level--;
|
||||||
|
src += 4;
|
||||||
|
|
||||||
|
} else if (isEndc(src)) {
|
||||||
|
level--;
|
||||||
|
if (level != 0) {
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (*src=='\"') {
|
||||||
|
inString = true;
|
||||||
|
}
|
||||||
|
src++;
|
||||||
}
|
}
|
||||||
else if( *src=='\"' )
|
} else {
|
||||||
{
|
switch (*src) {
|
||||||
src+=1;
|
case '\\':
|
||||||
instring=0;
|
src += 2;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{
|
case '\"':
|
||||||
src+=1;
|
src++;
|
||||||
|
inString = false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
src++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,57 +366,56 @@ void if_skip_to_else( void )
|
|||||||
fatalerror("Unterminated IF construct");
|
fatalerror("Unterminated IF construct");
|
||||||
}
|
}
|
||||||
|
|
||||||
len=src-pCurrentBuffer->pBuffer;
|
SLONG len = src - pCurrentBuffer->pBuffer;
|
||||||
|
|
||||||
yyskipbytes( len );
|
yyskipbytes(len);
|
||||||
yyunput( '\n' );
|
yyunput('\n');
|
||||||
nLineNo-=1;
|
nLineNo--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void if_skip_to_endc( void )
|
void if_skip_to_endc()
|
||||||
{
|
{
|
||||||
SLONG level=1, len, instring=0;
|
SLONG level = 1;
|
||||||
char *src=pCurrentBuffer->pBuffer;
|
bool inString = false;
|
||||||
|
char *src=pCurrentBuffer->pBuffer;
|
||||||
|
|
||||||
while( *src && level )
|
while (*src && level) {
|
||||||
{
|
if (*src == '\n') {
|
||||||
if( *src=='\n' )
|
nLineNo++;
|
||||||
nLineNo+=1;
|
}
|
||||||
|
|
||||||
if( instring==0 )
|
if (!inString) {
|
||||||
{
|
if (isIf(src)) {
|
||||||
if( isIf(src) )
|
level++;
|
||||||
{
|
src += 2;
|
||||||
level+=1;
|
|
||||||
src+=2;
|
} else if (isEndc(src)) {
|
||||||
}
|
level--;
|
||||||
else if( isEndc(src) )
|
if (level != 0) {
|
||||||
{
|
src += 4;
|
||||||
level-=1;
|
}
|
||||||
if( level!=0 )
|
|
||||||
src+=4;
|
} else {
|
||||||
}
|
if (*src=='\"') {
|
||||||
else
|
inString = true;
|
||||||
{
|
}
|
||||||
if( *src=='\"' )
|
src++;
|
||||||
instring=1;
|
|
||||||
src+=1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
switch (*src) {
|
||||||
if( *src=='\\' )
|
case '\\':
|
||||||
{
|
src += 2;
|
||||||
src+=2;
|
break;
|
||||||
}
|
|
||||||
else if( *src=='\"' )
|
case '\"':
|
||||||
{
|
src++;
|
||||||
src+=1;
|
inString = false;
|
||||||
instring=0;
|
break;
|
||||||
}
|
|
||||||
else
|
default:
|
||||||
{
|
src++;
|
||||||
src+=1;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,11 +424,11 @@ void if_skip_to_endc( void )
|
|||||||
fatalerror("Unterminated IF construct");
|
fatalerror("Unterminated IF construct");
|
||||||
}
|
}
|
||||||
|
|
||||||
len=src-pCurrentBuffer->pBuffer;
|
SLONG len = src - pCurrentBuffer->pBuffer;
|
||||||
|
|
||||||
yyskipbytes( len );
|
yyskipbytes(len);
|
||||||
yyunput( '\n' );
|
yyunput('\n');
|
||||||
nLineNo-=1;
|
nLineNo--;
|
||||||
}
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
@@ -492,7 +496,7 @@ void if_skip_to_endc( void )
|
|||||||
%token <tzSym> T_POP_SET
|
%token <tzSym> T_POP_SET
|
||||||
%token <tzSym> T_POP_EQUS
|
%token <tzSym> T_POP_EQUS
|
||||||
|
|
||||||
%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_IF T_POP_ELSE T_POP_ENDC
|
%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_IF T_POP_ELIF T_POP_ELSE T_POP_ENDC
|
||||||
%token T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL
|
%token T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL
|
||||||
%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL
|
%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL
|
||||||
%token T_POP_SECTION
|
%token T_POP_SECTION
|
||||||
@@ -627,6 +631,7 @@ simple_pseudoop : include
|
|||||||
| printt
|
| printt
|
||||||
| printv
|
| printv
|
||||||
| if
|
| if
|
||||||
|
| elif
|
||||||
| else
|
| else
|
||||||
| endc
|
| endc
|
||||||
| import
|
| import
|
||||||
@@ -867,26 +872,47 @@ printf : T_POP_PRINTF const
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
if : T_POP_IF const
|
if : T_POP_IF const {
|
||||||
{
|
nIFDepth++;
|
||||||
nIFDepth+=1;
|
if (!$2) {
|
||||||
if( !$2 )
|
if_skip_to_else(); // Continue parsing after ELSE, or at ELIF or ENDC keyword
|
||||||
{
|
|
||||||
if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
else : T_POP_ELSE
|
elif : T_POP_ELIF const {
|
||||||
{
|
if (nIFDepth <= 0) {
|
||||||
if_skip_to_endc(); /* will continue parsing just at ENDC keyword */
|
fatalerror("Found ELIF outside an IF construct");
|
||||||
}
|
}
|
||||||
;
|
|
||||||
|
|
||||||
endc : T_POP_ENDC
|
if (skipElif) {
|
||||||
{
|
// This is for when ELIF is reached at the end of an IF or ELIF block for which the condition was true.
|
||||||
nIFDepth-=1;
|
if_skip_to_endc(); // Continue parsing at ENDC keyword
|
||||||
}
|
|
||||||
;
|
} else {
|
||||||
|
// This is for when ELIF is skipped to because the condition of the previous IF or ELIF block was false.
|
||||||
|
skipElif = true;
|
||||||
|
|
||||||
|
if (!$2) {
|
||||||
|
if_skip_to_else(); // Continue parsing after ELSE, or at ELIF or ENDC keyword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
else : T_POP_ELSE {
|
||||||
|
if (nIFDepth <= 0) {
|
||||||
|
fatalerror("Found ELSE outside an IF construct");
|
||||||
|
}
|
||||||
|
|
||||||
|
if_skip_to_endc(); // Continue parsing at ENDC keyword
|
||||||
|
};
|
||||||
|
|
||||||
|
endc : T_POP_ENDC {
|
||||||
|
if (nIFDepth <= 0) {
|
||||||
|
fatalerror("Found ENDC outside an IF construct");
|
||||||
|
}
|
||||||
|
|
||||||
|
nIFDepth--;
|
||||||
|
};
|
||||||
|
|
||||||
const_3bit : const
|
const_3bit : const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -329,6 +329,7 @@ struct sLexInitString staticstrings[] = {
|
|||||||
|
|
||||||
{"if", T_POP_IF},
|
{"if", T_POP_IF},
|
||||||
{"else", T_POP_ELSE},
|
{"else", T_POP_ELSE},
|
||||||
|
{"elif", T_POP_ELIF},
|
||||||
{"endc", T_POP_ENDC},
|
{"endc", T_POP_ENDC},
|
||||||
|
|
||||||
{"wram0", T_SECT_WRAM0},
|
{"wram0", T_SECT_WRAM0},
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ char **cldefines;
|
|||||||
clock_t nStartClock, nEndClock;
|
clock_t nStartClock, nEndClock;
|
||||||
SLONG nLineNo;
|
SLONG nLineNo;
|
||||||
ULONG nTotalLines, nPass, nPC, nIFDepth, nErrors;
|
ULONG nTotalLines, nPass, nPC, nIFDepth, nErrors;
|
||||||
|
bool skipElif;
|
||||||
|
|
||||||
extern int yydebug;
|
extern int yydebug;
|
||||||
|
|
||||||
@@ -414,6 +415,7 @@ main(int argc, char *argv[])
|
|||||||
nLineNo = 1;
|
nLineNo = 1;
|
||||||
nTotalLines = 0;
|
nTotalLines = 0;
|
||||||
nIFDepth = 0;
|
nIFDepth = 0;
|
||||||
|
skipElif = true;
|
||||||
nPC = 0;
|
nPC = 0;
|
||||||
nPass = 1;
|
nPass = 1;
|
||||||
nErrors = 0;
|
nErrors = 0;
|
||||||
@@ -440,6 +442,7 @@ main(int argc, char *argv[])
|
|||||||
nTotalLines = 0;
|
nTotalLines = 0;
|
||||||
nLineNo = 1;
|
nLineNo = 1;
|
||||||
nIFDepth = 0;
|
nIFDepth = 0;
|
||||||
|
skipElif = true;
|
||||||
nPC = 0;
|
nPC = 0;
|
||||||
nPass = 2;
|
nPass = 2;
|
||||||
nErrors = 0;
|
nErrors = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user