ref: 5c7db42fc4bdbd4a7755423876b7554addf86799
parent: 4be92e14e622f0e8d01737e37a0e60f87a7d8a40
author: YamaArashi <[email protected]>
date: Fri Aug 22 22:55:52 EDT 2014
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).
--- a/include/asm/asm.h
+++ b/include/asm/asm.h
@@ -23,6 +23,7 @@
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];
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -289,71 +289,76 @@
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 {
+ switch (*src) {
+ case '\\':
+ src += 2;
+ break;
+
+ case '\"':
+ src++;
+ inString = false;
+
+ default:
+ src++;
+ break;
}
- else
- {
- src+=1;
- }
}
}
@@ -361,58 +366,57 @@
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;
+ 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( isEndc(src) )
- {
- level-=1;
- if( level!=0 )
- src+=4;
- }
- else
- {
- if( *src=='\"' )
- instring=1;
- src+=1;
- }
}
- else
- {
- if( *src=='\\' )
- {
- src+=2;
+ else {
+ switch (*src) {
+ case '\\':
+ src += 2;
+ break;
+
+ case '\"':
+ src++;
+ inString = false;
+ break;
+
+ default:
+ src++;
+ break;
}
- else if( *src=='\"' )
- {
- src+=1;
- instring=0;
- }
- else
- {
- src+=1;
- }
}
}
@@ -420,11 +424,11 @@
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 @@
%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 @@
| printt
| printv
| if
+ | elif
| else
| endc
| import
@@ -867,26 +872,47 @@
}
;
-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
{
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -329,6 +329,7 @@
{"if", T_POP_IF},
{"else", T_POP_ELSE},
+ {"elif", T_POP_ELIF},
{"endc", T_POP_ENDC},
{"wram0", T_SECT_WRAM0},
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -23,6 +23,7 @@
clock_t nStartClock, nEndClock;
SLONG nLineNo;
ULONG nTotalLines, nPass, nPC, nIFDepth, nErrors;
+bool skipElif;
extern int yydebug;
@@ -414,6 +415,7 @@
nLineNo = 1;
nTotalLines = 0;
nIFDepth = 0;
+ skipElif = true;
nPC = 0;
nPass = 1;
nErrors = 0;
@@ -440,6 +442,7 @@
nTotalLines = 0;
nLineNo = 1;
nIFDepth = 0;
+ skipElif = true;
nPC = 0;
nPass = 2;
nErrors = 0;