diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index 8ee9aa52..2b24e15b 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -817,6 +817,11 @@ static int peek() { shiftChar(); if (std::shared_ptr str = readMacroArg(); str) { beginExpansion(str, std::nullopt); + + // Mark the entire macro arg expansion as "painted blue" + // so that macro args can't be recursive + // https://en.wikipedia.org/wiki/Painted_blue + lexerState->macroArgScanDistance += str->length(); } } else if (c == '{' && !lexerState->disableInterpolation) { // If character is an open brace, do symbol interpolation diff --git a/test/asm/macro-arg-recursion.asm b/test/asm/macro-arg-recursion.asm new file mode 100644 index 00000000..d2b6103d --- /dev/null +++ b/test/asm/macro-arg-recursion.asm @@ -0,0 +1,6 @@ +MACRO m + def x = (\1) * 2 + println "{d:x}" +ENDM + m 5 ; prints 10 + m \\2, 6 ; should not prints 12 diff --git a/test/asm/macro-arg-recursion.err b/test/asm/macro-arg-recursion.err new file mode 100644 index 00000000..ae7efe51 --- /dev/null +++ b/test/asm/macro-arg-recursion.err @@ -0,0 +1,3 @@ +error: macro-arg-recursion.asm(6) -> macro-arg-recursion.asm::m(2): + Begun line continuation, but encountered character '2' +Assembly aborted with 1 error! diff --git a/test/asm/macro-arg-recursion.out b/test/asm/macro-arg-recursion.out new file mode 100644 index 00000000..9c963fff --- /dev/null +++ b/test/asm/macro-arg-recursion.out @@ -0,0 +1,2 @@ +10 +4