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 nPass;
extern ULONG nIFDepth;
extern bool skipElif;
extern char tzCurrentFileName[_MAX_PATH + 1];
extern struct Section *pCurrentSection;
extern struct sSymbol *tHashedSymbols[HASHSIZE];

View File

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

View File

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

View File

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