shithub: rgbds

Download patch

ref: aa99ed056c44b93449c3333e104858009bde357d
parent: 46d6652df110b62ea1fcbc21400bb50937457e76
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Sun Mar 21 20:25:22 EDT 2021

Do not evaluate an untaken ELIF's condition

Fixes #764

--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -1856,6 +1856,8 @@
 
 /* Lexer core */
 
+static int yylex_SKIP_TO_ENDC(void); // forward declaration for yylex_NORMAL
+
 static int yylex_NORMAL(void)
 {
 	dbgPrint("Lexing in normal mode, line=%" PRIu32 ", col=%" PRIu32 "\n",
@@ -2084,6 +2086,12 @@
 		default:
 			if (startsIdentifier(c)) {
 				int tokenType = readIdentifier(c);
+
+				/* An ELIF after a taken IF needs to not evaluate its condition */
+				if (tokenType == T_POP_ELIF && lexerState->lastToken == T_NEWLINE
+				 && lexer_GetIFDepth() > 0 && lexer_RanIFBlock()
+				 && !lexer_ReachedELSEBlock())
+					return yylex_SKIP_TO_ENDC();
 
 				/* If a keyword, don't try to expand */
 				if (tokenType != T_ID && tokenType != T_LOCAL_ID)
--- /dev/null
+++ b/test/asm/elif-after-taken-if.asm
@@ -1,0 +1,23 @@
+if 1
+	println "taken if"
+elif 2 / 0 ; avoided fatal "Division by zero" error
+	println "untaken elif"
+elif 3 / 0 ; avoided fatal "Division by zero" error
+	println "untaken after untaken"
+endc
+
+if 0
+	println "untaken if"
+elif 1
+	println "taken elif"
+elif !@#$ ; avoided fatal syntax error
+	println "untaken elif"
+elif %^&* ; avoided fatal syntax error
+	println "untaken after untaken"
+endc
+
+if 0
+	println "untaken if"
+elif 1 / 0 ; fatal "Division by zero" error
+	println "unreached elif"
+endc
--- /dev/null
+++ b/test/asm/elif-after-taken-if.err
@@ -1,0 +1,2 @@
+FATAL: elif-after-taken-if.asm(21):
+    Division by zero
--- /dev/null
+++ b/test/asm/elif-after-taken-if.out
@@ -1,0 +1,2 @@
+taken if
+taken elif
--- a/test/asm/skip-elif-condition.asm
+++ b/test/asm/skip-elif-condition.asm
@@ -3,7 +3,7 @@
 		println "small \1"
 	elif (\1) > 100
 		println "large \1"
-	elif (\1) / 0 == 42 ; only evaluated if the "large" condition was taken
+	elif (\1) / 0 == 42 ; only evaluated if neither "small" nor "large" was taken
 		println "division by zero!?"
 	elif syntax! error?
 		println "X_X"
@@ -15,3 +15,4 @@
 	mac 2 + 2
 	mac STRLEN("abcdef")
 	mac 101
+	mac 23
--- a/test/asm/skip-elif-condition.err
+++ b/test/asm/skip-elif-condition.err
@@ -1,2 +1,2 @@
-FATAL: skip-elif-condition.asm(17) -> skip-elif-condition.asm::mac(6):
+FATAL: skip-elif-condition.asm(18) -> skip-elif-condition.asm::mac(6):
     Division by zero