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:
YamaArashi
2014-08-23 02:55:52 -07:00
committed by Ben10do
parent 4be92e14e6
commit 5c7db42fc4
4 changed files with 146 additions and 115 deletions

View File

@@ -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];

View File

@@ -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
{ {

View File

@@ -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},

View File

@@ -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;