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 nPass;
|
||||
extern ULONG nIFDepth;
|
||||
extern bool skipElif;
|
||||
extern char tzCurrentFileName[_MAX_PATH + 1];
|
||||
extern struct Section *pCurrentSection;
|
||||
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 );
|
||||
}
|
||||
|
||||
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;
|
||||
char *src=pCurrentBuffer->pBuffer;
|
||||
return((strncasecmp(s,"Endc",4) == 0) && isWhiteSpace(s[-1]) && isWhiteSpace(s[4]));
|
||||
}
|
||||
|
||||
while( *src && level )
|
||||
{
|
||||
if( *src=='\n' )
|
||||
nLineNo+=1;
|
||||
void if_skip_to_else()
|
||||
{
|
||||
SLONG level = 1;
|
||||
bool inString = false;
|
||||
char *src=pCurrentBuffer->pBuffer;
|
||||
|
||||
if( instring==0 )
|
||||
{
|
||||
if( isIf(src) )
|
||||
{
|
||||
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;
|
||||
}
|
||||
while (*src && level) {
|
||||
if (*src == '\n') {
|
||||
nLineNo++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( *src=='\\' )
|
||||
{
|
||||
src+=2;
|
||||
|
||||
if (!inString) {
|
||||
if (isIf(src)) {
|
||||
level++;
|
||||
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=='\"' )
|
||||
{
|
||||
src+=1;
|
||||
instring=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
src+=1;
|
||||
} else {
|
||||
switch (*src) {
|
||||
case '\\':
|
||||
src += 2;
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
src++;
|
||||
inString = false;
|
||||
|
||||
default:
|
||||
src++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,57 +366,56 @@ void if_skip_to_else( void )
|
||||
fatalerror("Unterminated IF construct");
|
||||
}
|
||||
|
||||
len=src-pCurrentBuffer->pBuffer;
|
||||
SLONG len = src - pCurrentBuffer->pBuffer;
|
||||
|
||||
yyskipbytes( len );
|
||||
yyunput( '\n' );
|
||||
nLineNo-=1;
|
||||
yyskipbytes(len);
|
||||
yyunput('\n');
|
||||
nLineNo--;
|
||||
}
|
||||
|
||||
void if_skip_to_endc( void )
|
||||
void if_skip_to_endc()
|
||||
{
|
||||
SLONG level=1, len, instring=0;
|
||||
char *src=pCurrentBuffer->pBuffer;
|
||||
SLONG level = 1;
|
||||
bool inString = false;
|
||||
char *src=pCurrentBuffer->pBuffer;
|
||||
|
||||
while( *src && level )
|
||||
{
|
||||
if( *src=='\n' )
|
||||
nLineNo+=1;
|
||||
while (*src && level) {
|
||||
if (*src == '\n') {
|
||||
nLineNo++;
|
||||
}
|
||||
|
||||
if( instring==0 )
|
||||
{
|
||||
if( isIf(src) )
|
||||
{
|
||||
level+=1;
|
||||
src+=2;
|
||||
}
|
||||
else if( isEndc(src) )
|
||||
{
|
||||
level-=1;
|
||||
if( level!=0 )
|
||||
src+=4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( *src=='\"' )
|
||||
instring=1;
|
||||
src+=1;
|
||||
if (!inString) {
|
||||
if (isIf(src)) {
|
||||
level++;
|
||||
src += 2;
|
||||
|
||||
} else if (isEndc(src)) {
|
||||
level--;
|
||||
if (level != 0) {
|
||||
src += 4;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (*src=='\"') {
|
||||
inString = true;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( *src=='\\' )
|
||||
{
|
||||
src+=2;
|
||||
}
|
||||
else if( *src=='\"' )
|
||||
{
|
||||
src+=1;
|
||||
instring=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
src+=1;
|
||||
else {
|
||||
switch (*src) {
|
||||
case '\\':
|
||||
src += 2;
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
src++;
|
||||
inString = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
src++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -420,11 +424,11 @@ void if_skip_to_endc( void )
|
||||
fatalerror("Unterminated IF construct");
|
||||
}
|
||||
|
||||
len=src-pCurrentBuffer->pBuffer;
|
||||
SLONG len = src - pCurrentBuffer->pBuffer;
|
||||
|
||||
yyskipbytes( len );
|
||||
yyunput( '\n' );
|
||||
nLineNo-=1;
|
||||
yyskipbytes(len);
|
||||
yyunput('\n');
|
||||
nLineNo--;
|
||||
}
|
||||
|
||||
%}
|
||||
@@ -492,7 +496,7 @@ void if_skip_to_endc( void )
|
||||
%token <tzSym> T_POP_SET
|
||||
%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_DB T_POP_DS T_POP_DW T_POP_DL
|
||||
%token T_POP_SECTION
|
||||
@@ -627,6 +631,7 @@ simple_pseudoop : include
|
||||
| printt
|
||||
| printv
|
||||
| if
|
||||
| elif
|
||||
| else
|
||||
| endc
|
||||
| import
|
||||
@@ -867,26 +872,47 @@ printf : T_POP_PRINTF const
|
||||
}
|
||||
;
|
||||
|
||||
if : T_POP_IF const
|
||||
{
|
||||
nIFDepth+=1;
|
||||
if( !$2 )
|
||||
{
|
||||
if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */
|
||||
if : T_POP_IF const {
|
||||
nIFDepth++;
|
||||
if (!$2) {
|
||||
if_skip_to_else(); // Continue parsing after ELSE, or at ELIF or ENDC keyword
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
else : T_POP_ELSE
|
||||
{
|
||||
if_skip_to_endc(); /* will continue parsing just at ENDC keyword */
|
||||
}
|
||||
;
|
||||
elif : T_POP_ELIF const {
|
||||
if (nIFDepth <= 0) {
|
||||
fatalerror("Found ELIF outside an IF construct");
|
||||
}
|
||||
|
||||
endc : T_POP_ENDC
|
||||
{
|
||||
nIFDepth-=1;
|
||||
}
|
||||
;
|
||||
if (skipElif) {
|
||||
// This is for when ELIF is reached at the end of an IF or ELIF block for which the condition was true.
|
||||
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
|
||||
{
|
||||
|
||||
@@ -329,6 +329,7 @@ struct sLexInitString staticstrings[] = {
|
||||
|
||||
{"if", T_POP_IF},
|
||||
{"else", T_POP_ELSE},
|
||||
{"elif", T_POP_ELIF},
|
||||
{"endc", T_POP_ENDC},
|
||||
|
||||
{"wram0", T_SECT_WRAM0},
|
||||
|
||||
@@ -23,6 +23,7 @@ char **cldefines;
|
||||
clock_t nStartClock, nEndClock;
|
||||
SLONG nLineNo;
|
||||
ULONG nTotalLines, nPass, nPC, nIFDepth, nErrors;
|
||||
bool skipElif;
|
||||
|
||||
extern int yydebug;
|
||||
|
||||
@@ -414,6 +415,7 @@ main(int argc, char *argv[])
|
||||
nLineNo = 1;
|
||||
nTotalLines = 0;
|
||||
nIFDepth = 0;
|
||||
skipElif = true;
|
||||
nPC = 0;
|
||||
nPass = 1;
|
||||
nErrors = 0;
|
||||
@@ -440,6 +442,7 @@ main(int argc, char *argv[])
|
||||
nTotalLines = 0;
|
||||
nLineNo = 1;
|
||||
nIFDepth = 0;
|
||||
skipElif = true;
|
||||
nPC = 0;
|
||||
nPass = 2;
|
||||
nErrors = 0;
|
||||
|
||||
Reference in New Issue
Block a user