You might be having problems with some of the unusual syntax of ObjectScript.
Like other languages created in the 1960s (E.g., FORTRAN IV and PL/I), ObjectScript does not have any reserved words. The word 'if' can be a command if it appears where a command is specified; it can be local variable if it appears where an expression value is expected; it can sometimes be a global variable or program name if it appears after '^'; it can be a function name if it appears after '$$'; it can be a macro name if it appears after '$$$'; it be a routine or procedure name if it appears after the 'do' command; if can sometimes be a method or a property name if it appears after '.'; etc.
Your macros
#define TestIf(%arr) if %arr>0 QUIT 5 ;; legacy IF command
#define TestIf(%arr) if (%arr>0) {QUIT 5} ;; more modern IF command
looks as if TestIf should be expanded where a command is expected so that it conditionally executes the command 'QUIT 5' which would exit the current function with a return value of 5.
However, your macro placement
set a = $$$TestIf(3)
looks like $$$TestIf is going to be an expression containing a value for the right side of an assignment (a SET command). It expands as
set a = if 3 < 0 QUIT 5
which is a syntactically correct assignment of 'a' assigned the value of the variable 'if' and that 'set' command is followed by a command named '3' which is bad syntax.
Your macro
#define logDebug(%arr) $SELECT(^GlFSL("Debug")>0:Entry^HS.Local.VA.Util.Log(%arr,,"D"),:QUIT)
looks like a macro containing the built-in '$select' function and the macro should expand into conditional expression (as opposed to a macro containing the command 'if' which should expand in to a conditional statement.) The first $select argument ^GlFSL("Debug")>0:Entry^HS.Local.VA.Util.Log(%arr,,"D") evaluates ^GlFSL("Debug")>0 and it that comparison is true, the $select evaluates Entry^HS.Local.VA.Util.Log(%arr,,"D") as the final value of the $select expression. If the selector of the first argument is false then $select goes on the second argument ,:QUIT. This has the syntax for the default value of a argument of the built-in $case function rather than be correct syntax for a $select argument. For a $select you would write 1:QUIT which would return the value of the QUIT variable. However, I suspect you might have wanted a QUIT command which would terminated the current routine/procedure. In that case you should write the conditional commands
if ^GlFSL("Debug")>0 then { set temp=Entry^HS.Local.VA.Util.Log(%arr,,"D")} else {QUIT}
if you do not execute the QUIT command then you can continue executing the next command line using the conditionally set 'temp' variable.
The JSON standard does not support nested, circular objects. The IEEE Standards Association did call for a committee to be formed to extend JSON to include graphs of objects but there was not enough interest to form such a committee.
I seriously doubt it is a %Regex issue. The ? appears when some interface is converting characters to one of the many 8-bit character set codes and the source character code has a character that is not in the destination character code. This can happen to about 2**20 characters of Unicode when they are converted to any 8-bit code. It can also happen when converting 8-bit to a different 8-bit code.
Your terminal emulator and the IRIS terminal device can both do such conversions. A IRIS file device can also do such conversions. Different platforms can use different default conversions which explains why some different people cannot reproduce the results of other people.