@@ -530,14 +530,15 @@ export function Tokenizer() {
530530 const [ tokens , setTokens ] = useState < Token [ ] > ( [ ] ) ;
531531 const [ isRunning , setIsRunning ] = useState ( false ) ;
532532
533- const runTokenizer = async ( ) => {
534- if ( isRunning ) return ;
533+ const runTokenizer = async ( shouldStop : ( ) => boolean ) => {
534+ if ( isRunning || shouldStop ( ) ) return ;
535535 setIsRunning ( true ) ;
536536 setTokens ( [ ] ) ;
537537 setHighlight ( { start : 0 , end : 0 } ) ;
538538
539539 try {
540540 await tokenize ( fib10 , async ( newHighlight , newTokens ) => {
541+ if ( shouldStop ( ) ) return ;
541542 setHighlight ( newHighlight ) ;
542543 setTokens ( [ ...newTokens ] ) ;
543544 await new Promise ( resolve => setTimeout ( resolve , 150 ) ) ;
@@ -547,21 +548,26 @@ export function Tokenizer() {
547548 }
548549
549550 // Sleep for 2 seconds before allowing next run
550- await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
551+ if ( ! shouldStop ( ) ) {
552+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
553+ }
551554 setIsRunning ( false ) ;
552555 } ;
553556
554557 // Auto-start tokenization loop
555558 useEffect ( ( ) => {
556- let shouldContinue = true ;
559+ // Only run in browser environment
560+ if ( typeof window === 'undefined' ) return ;
561+
562+ let cancelled = false ;
557563 const loop = async ( ) => {
558- while ( shouldContinue ) {
559- await runTokenizer ( ) ;
564+ while ( ! cancelled ) {
565+ await runTokenizer ( ( ) => cancelled ) ;
560566 }
561567 } ;
562568 loop ( ) ;
563569 return ( ) => {
564- shouldContinue = false ;
570+ cancelled = true ;
565571 } ;
566572 } , [ ] ) ;
567573
@@ -688,8 +694,8 @@ export function Compiler() {
688694 const [ bytecode , setBytecode ] = useState < Bytecode [ ] > ( [ ] ) ;
689695 const [ isRunning , setIsRunning ] = useState ( false ) ;
690696
691- const runCompiler = async ( ) => {
692- if ( isRunning ) return ;
697+ const runCompiler = async ( shouldStop : ( ) => boolean ) => {
698+ if ( isRunning || shouldStop ( ) ) return ;
693699 setIsRunning ( true ) ;
694700 setTokens ( [ ] ) ;
695701 setBytecode ( [ ] ) ;
@@ -703,6 +709,7 @@ export function Compiler() {
703709
704710 // Then compile with highlighting
705711 await compile ( allTokens , async ( highlight , newBytecode ) => {
712+ if ( shouldStop ( ) ) return ;
706713 setHighlightRange ( { start : highlight . tokenIdxStart , end : highlight . tokenIdxEnd } ) ;
707714 setTokens ( [ ...allTokens ] ) ;
708715 setBytecode ( [ ...newBytecode ] ) ;
@@ -713,23 +720,26 @@ export function Compiler() {
713720 }
714721
715722 // Sleep for 2 seconds before next run
716- await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
723+ if ( ! shouldStop ( ) ) {
724+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
725+ }
717726 setIsRunning ( false ) ;
718727 } ;
719728
720729 useEffect ( ( ) => {
721- let shouldContinue = true ;
730+ // Only run in browser environment
731+ if ( typeof window === 'undefined' ) return ;
732+
733+ let cancelled = false ;
722734 const loop = async ( ) => {
723- while ( shouldContinue ) {
724- while ( true ) {
725- await runCompiler ( ) ;
726- }
735+ while ( ! cancelled ) {
736+ await runCompiler ( ( ) => cancelled ) ;
727737 }
728- return ( ) => {
729- shouldContinue = false ;
730- } ;
731738 } ;
732739 loop ( ) ;
740+ return ( ) => {
741+ cancelled = true ;
742+ } ;
733743 } , [ ] ) ;
734744
735745 // Calculate which tokens to show
@@ -852,8 +862,8 @@ export function VM() {
852862 const [ variableTable , setVariableTable ] = useState < number [ ] > ( [ ] ) ;
853863 const [ isRunning , setIsRunning ] = useState ( false ) ;
854864
855- const runVM = async ( ) => {
856- if ( isRunning ) return ;
865+ const runVM = async ( shouldStop : ( ) => boolean ) => {
866+ if ( isRunning || shouldStop ( ) ) return ;
857867 setIsRunning ( true ) ;
858868 setBytecode ( [ ] ) ;
859869 setDataStack ( [ ] ) ;
@@ -875,6 +885,7 @@ export function VM() {
875885
876886 // Run the VM with highlighting
877887 await vm ( program , async ( highlight , newDataStack , newReturnStack , newVariableTable ) => {
888+ if ( shouldStop ( ) ) return ;
878889 setHighlightIP ( highlight . ip ) ;
879890 setDataStack ( [ ...newDataStack ] ) ;
880891 setReturnStack ( [ ...newReturnStack ] ) ;
@@ -886,21 +897,26 @@ export function VM() {
886897 }
887898
888899 // Sleep for 2 seconds before next run
889- await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
900+ if ( ! shouldStop ( ) ) {
901+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
902+ }
890903 setIsRunning ( false ) ;
891904 } ;
892905
893906 useEffect ( ( ) => {
894- let shouldContinue = true ;
907+ // Only run in browser environment
908+ if ( typeof window === 'undefined' ) return ;
909+
910+ let cancelled = false ;
895911 const loop = async ( ) => {
896- while ( shouldContinue ) {
897- await runVM ( ) ;
912+ while ( ! cancelled ) {
913+ await runVM ( ( ) => cancelled ) ;
898914 }
899- return ( ) => {
900- shouldContinue = false ;
901- } ;
902915 } ;
903916 loop ( ) ;
917+ return ( ) => {
918+ cancelled = true ;
919+ } ;
904920 } , [ ] ) ;
905921
906922 // Calculate which bytecode lines to show (scrolled around IP)
0 commit comments