shithub: rgbds

Download patch

ref: e3d355d9762b5f50697274b25b685a0e3c16981a
parent: a679e0224603ca629bff991a470b8ad60ecfd053
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Thu Jan 21 04:36:10 EST 2021

Attempt to recover from syntax errors with bison

Fixes #595

--- a/include/asm/fstack.h
+++ b/include/asm/fstack.h
@@ -78,6 +78,7 @@
 void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size);
 void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
 		     int32_t reptLineNo, char *body, size_t size);
+void fstk_StopRept(void);
 bool fstk_Break(void);
 
 void fstk_Init(char const *mainPath, size_t maxRecursionDepth);
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -506,6 +506,12 @@
 		fatalerror("Not enough memory for FOR symbol name: %s\n", strerror(errno));
 }
 
+void fstk_StopRept(void)
+{
+	/* Prevent more iterations */
+	contextStack->nbReptIters = 0;
+}
+
 bool fstk_Break(void)
 {
 	dbgPrint("Breaking out of REPT/FOR\n");
@@ -515,8 +521,7 @@
 		return false;
 	}
 
-	/* Prevent more iterations */
-	contextStack->nbReptIters = 0;
+	fstk_StopRept();
 	return true;
 }
 
--- a/src/asm/parser.y
+++ b/src/asm/parser.y
@@ -609,6 +609,9 @@
 		| label directive T_NEWLINE
 		| assignment_directive T_NEWLINE
 		| line_directive /* Directives that manage newlines themselves */
+		| error T_NEWLINE { /* Continue parsing the next line on a syntax error */
+			fstk_StopRept();
+		}
 ;
 
 /*
--- /dev/null
+++ b/test/asm/error-recovery.asm
@@ -1,0 +1,11 @@
+	println "begin"
+
+	println 42, 1 2 3 4
+
+for n, 5
+	println "start {d:n}"
+	println syntax error
+	println "finish {d:n}"
+endr
+
+	println "end {d:n}"
--- /dev/null
+++ b/test/asm/error-recovery.err
@@ -1,0 +1,5 @@
+ERROR: error-recovery.asm(3):
+    syntax error, unexpected number
+ERROR: error-recovery.asm(5) -> error-recovery.asm::REPT~1(7):
+    syntax error, unexpected identifier
+error: Assembly aborted (2 errors)!
--- /dev/null
+++ b/test/asm/error-recovery.out
@@ -1,0 +1,4 @@
+begin
+$2Astart 0
+finish 0
+end 0
--- /dev/null
+++ b/test/asm/error-recovery.simple.err
@@ -1,0 +1,5 @@
+ERROR: error-recovery.asm(3):
+    syntax error
+ERROR: error-recovery.asm(5) -> error-recovery.asm::REPT~1(7):
+    syntax error
+error: Assembly aborted (2 errors)!
--- a/test/asm/label-macro-arg.err
+++ b/test/asm/label-macro-arg.err
@@ -1,4 +1,19 @@
 ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(25):
     syntax error, unexpected =
 while expanding symbol "VAR_DEF"
-error: Assembly aborted (1 errors)!
+ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(29):
+    Interpolated symbol "sizeof_.something" does not exist
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25):
+    Label "sizeof_" created outside of a SECTION
+while expanding symbol "VAR_DEF"
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25):
+    Macro "something" not defined
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26):
+    'sizeof_' already defined at label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25)
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26):
+    Macro "something" not defined
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29):
+    Invalid format spec 'sizeof_'
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29):
+    Interpolated symbol "something" does not exist
+error: Assembly aborted (8 errors)!
--- a/test/asm/label-macro-arg.out
+++ b/test/asm/label-macro-arg.out
@@ -5,3 +5,5 @@
 sizeof__something equals $1
 sizeof_@something equals $1
 sizeof_#something equals $1
+sizeof_.something equals 
+sizeof_:something equals 
--- a/test/asm/label-macro-arg.simple.err
+++ b/test/asm/label-macro-arg.simple.err
@@ -4,4 +4,21 @@
 ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(25):
     syntax error
 while expanding symbol "VAR_DEF"
-error: Assembly aborted (2 errors)!
+ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(26):
+    Local label 'sizeof_.something' in main scope
+ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(29):
+    Interpolated symbol "sizeof_.something" does not exist
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25):
+    Label "sizeof_" created outside of a SECTION
+while expanding symbol "VAR_DEF"
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25):
+    Macro "something" not defined
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26):
+    'sizeof_' already defined at label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25)
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26):
+    Macro "something" not defined
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29):
+    Invalid format spec 'sizeof_'
+ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29):
+    Interpolated symbol "something" does not exist
+error: Assembly aborted (10 errors)!