@@ -324,6 +324,47 @@ struct VirtualMachine {
324324 }
325325 return nullptr ;
326326 }
327+ // Instead of tokenizing, the assembler simply splits everything after colon along commas to get the arguments.
328+ // To avoid splitting with commas inside of text used to create immediate values, only the commas outside of "" () [] {} are used to split.
329+ List<String> nestedCommaSplit (const ReadableString& source) {
330+ List<String> result;
331+ intptr_t sectionStart = 0 ;
332+ bool quoted = false ;
333+ intptr_t depth = 0 ;
334+ for (intptr_t i = 0 ; i < string_length (source); i++) {
335+ DsrChar c = source[i];
336+ if (quoted) {
337+ if (c == U' "' ) {
338+ quoted = false ;
339+ } else if (c == U' \\ ' ) {
340+ // Skip one character after escape.
341+ i++;
342+ }
343+ } else {
344+ if (c == U' "' ) {
345+ quoted = true ;
346+ } else if (c == U' ,' and depth == 0 ) {
347+ ReadableString element = string_exclusiveRange (source, sectionStart, i);
348+ result.push (string_removeOuterWhiteSpace (element));
349+ sectionStart = i + 1 ;
350+ } else if (c == U' (' || c == U' [' || c == U' {' ) {
351+ depth++;
352+ } else if (c == U' )' || c == U' ]' || c == U' }' ) {
353+ depth--;
354+ }
355+ }
356+ }
357+ if (string_length (source) > sectionStart) {
358+ result.push (string_removeOuterWhiteSpace (string_exclusiveRange (source, sectionStart, string_length (source))));
359+ }
360+ if (quoted) {
361+ throwError (U" Quotes may not contain unmangled line-breaks in virtual machine assembler code!\n " );
362+ }
363+ if (depth != 0 ) {
364+ throwError (U" Immediate constants must balance expressions containing () [] {}, because otherwise parsing of virtual machine assembler code can not know which commas are used to separate arguments!\n " );
365+ }
366+ return result;
367+ }
327368 // Constructor
328369 VirtualMachine (const ReadableString& code, const Handle<PlanarMemory<TYPE_COUNT>>& memory,
329370 const InsSig<TYPE_COUNT>* machineInstructions, int32_t machineInstructionCount,
@@ -348,7 +389,7 @@ struct VirtualMachine {
348389 if (colonIndex > -1 ) {
349390 ReadableString command = string_removeOuterWhiteSpace (string_before (currentLine, colonIndex));
350391 ReadableString argumentLine = string_after (currentLine, colonIndex);
351- List<String> arguments = string_split (argumentLine, U ' , ' , true );
392+ List<String> arguments = nestedCommaSplit (argumentLine);
352393 this ->interpretMachineWord (command, arguments);
353394 } else if (string_length (currentLine) > 0 ) {
354395 throwError (U" Unexpected line \" " , currentLine, U" \" .\n " );
0 commit comments