@@ -417,7 +417,17 @@ <h2 style="margin: 0;">Fail-safe settings</h2>
417417 return settings ;
418418 }
419419
420- function runProgram ( program , inputs , failsafeSettings , onOutput ) {
420+ function waitForNextFrame ( ) {
421+ return new Promise ( ( resolve ) => {
422+ if ( typeof requestAnimationFrame === 'function' ) {
423+ requestAnimationFrame ( ( ) => resolve ( ) ) ;
424+ } else {
425+ setTimeout ( resolve , 0 ) ;
426+ }
427+ } ) ;
428+ }
429+
430+ async function runProgram ( program , inputs , failsafeSettings , onOutput ) {
421431 const commands = program . replace ( / [ ^ \> \< \+ \- \. \, \[ \] ] / g, '' ) ;
422432 const jumpMap = buildJumpMap ( commands ) ;
423433
@@ -428,6 +438,8 @@ <h2 style="margin: 0;">Fail-safe settings</h2>
428438 const output = [ ] ;
429439 const timeoutMs = failsafeSettings . timeoutSeconds * 1000 ;
430440 const startTime = performance . now ( ) ;
441+ const yieldInterval = 2000 ;
442+ let stepsUntilYield = yieldInterval ;
431443
432444 function enforceFailSafe ( message ) {
433445 const debugInfo = [
@@ -463,7 +475,7 @@ <h2 style="margin: 0;">Fail-safe settings</h2>
463475 case '.' :
464476 output . push ( tape [ pointer ] ) ;
465477 if ( onOutput ) {
466- onOutput ( tape [ pointer ] , output ) ;
478+ await onOutput ( tape [ pointer ] , output ) ;
467479 }
468480 break ;
469481 case ',' :
@@ -487,6 +499,12 @@ <h2 style="margin: 0;">Fail-safe settings</h2>
487499 enforceFailSafe ( `Execution stopped because the tape exceeded ${ failsafeSettings . tapeLengthLimit } cell${ failsafeSettings . tapeLengthLimit === 1 ? '' : 's' } .` ) ;
488500 }
489501 ip += 1 ;
502+
503+ stepsUntilYield -= 1 ;
504+ if ( stepsUntilYield <= 0 ) {
505+ stepsUntilYield = yieldInterval ;
506+ await waitForNextFrame ( ) ;
507+ }
490508 }
491509
492510 return output ;
@@ -513,20 +531,23 @@ <h2 style="margin: 0;">Fail-safe settings</h2>
513531 }
514532 }
515533
516- runButton . addEventListener ( 'click' , ( ) => {
534+ runButton . addEventListener ( 'click' , async ( ) => {
517535 try {
518536 const mode = asciiModeRadio . checked ? 'ascii' : 'numbers' ;
519537 const inputs = parseInputs ( bfInput . value , mode ) ;
520538 const program = editor . getValue ( ) ;
539+ updateStatus ( '' ) ;
521540 clearOutputs ( ) ;
541+ await waitForNextFrame ( ) ;
522542
523543 const liveOutput = [ ] ;
524- const onOutput = ( byte ) => {
544+ const onOutput = async ( byte ) => {
525545 liveOutput . push ( clampByte ( byte ) ) ;
526546 renderOutput ( liveOutput ) ;
547+ await waitForNextFrame ( ) ;
527548 } ;
528549
529- const output = runProgram ( program , inputs , collectFailsafeSettingsFromInputs ( ) , onOutput ) ;
550+ const output = await runProgram ( program , inputs , collectFailsafeSettingsFromInputs ( ) , onOutput ) ;
530551 renderOutput ( output ) ;
531552 updateStatus ( `Program ran successfully. Output length: ${ output . length } byte${ output . length === 1 ? '' : 's' } .` ) ;
532553 } catch ( error ) {
0 commit comments