@@ -106,6 +106,7 @@ class JSGenerator {
106106 this . isWarp = script . isWarp ;
107107 this . isProcedure = script . isProcedure ;
108108 this . warpTimer = script . warpTimer ;
109+ this . allowReturns = false ;
109110
110111 /**
111112 * Stack of frames, most recent is last item.
@@ -461,7 +462,22 @@ class JSGenerator {
461462 const procedureReference = `thread.procedures["${ sanitize ( procedureVariant ) } "]` ;
462463 const args = [ ] ;
463464 for ( const input of node . arguments ) {
464- args . push ( this . descendInput ( input ) ) ;
465+ if ( input instanceof IntermediateStack ) {
466+ const oldSource = this . source ;
467+ this . source = "function*(thread, target, runtime, stage) {\n" ;
468+ const oldWarp = this . isWarp ;
469+ this . isWarp = procedureData . isWarp ;
470+ const oldReturns = this . allowReturns ;
471+ this . allowReturns = true ;
472+ this . descendStack ( input ) ;
473+ this . source += `}` ;
474+ args . push ( this . source ) ;
475+ this . allowReturns = oldReturns ;
476+ this . isWarp = oldWarp ;
477+ this . source = oldSource ;
478+ } else {
479+ args . push ( this . descendInput ( input ) ) ;
480+ }
465481 }
466482 const joinedArgs = args . join ( ',' ) ;
467483
@@ -929,6 +945,8 @@ class JSGenerator {
929945 // Direct yields.
930946 this . yieldNotWarp ( ) ;
931947 }
948+ let outputVariable = this . localVariables . next ( ) ;
949+ this . source += `let ${ outputVariable } = ` ;
932950 if ( procedureData . yields ) {
933951 this . source += 'yield* ' ;
934952 if ( ! this . script . yields ) {
@@ -938,15 +956,43 @@ class JSGenerator {
938956 this . source += `thread.procedures["${ sanitize ( procedureVariant ) } "](` ;
939957 const args = [ ] ;
940958 for ( const input of node . arguments ) {
941- args . push ( this . descendInput ( input ) ) ;
959+ if ( input instanceof IntermediateStack ) {
960+ const oldSource = this . source ;
961+ this . source = "function*(thread, target, runtime, stage) {\n" ;
962+ const oldWarp = this . isWarp ;
963+ this . isWarp = procedureData . isWarp ;
964+ const oldReturns = this . allowReturns ;
965+ this . allowReturns = true ;
966+ this . descendStack ( input ) ;
967+ this . source += `}` ;
968+ args . push ( this . source ) ;
969+ this . allowReturns = oldReturns ;
970+ this . isWarp = oldWarp ;
971+ this . source = oldSource ;
972+ } else {
973+ args . push ( this . descendInput ( input ) ) ;
974+ }
942975 }
943976 this . source += args . join ( ',' ) ;
944977 this . source += `);\n` ;
978+ const thisData = this . ir . procedures [ this . script . procedureVariant ] ;
979+ if ( thisData && ! thisData . returns ) {
980+ this . source += `if (${ outputVariable } !== undefined) { return ${ outputVariable } ; };\n`
981+ }
945982 break ;
946983 }
947984 case StackOpcode . PROCEDURE_RETURN :
948985 this . stopScriptAndReturn ( this . descendInput ( node . value ) ) ;
949986 break ;
987+ case StackOpcode . PROCEDURE_BRANCH :
988+ if ( node . index !== - 1 ) {
989+ let outputVariable = this . localVariables . next ( ) ;
990+ this . source += `let ${ outputVariable } = yield* (p${ node . index } || function*(){})(thread, target, runtime, stage);\n` ;
991+ this . source += `if (${ outputVariable } !== undefined) {\n` ;
992+ this . stopScriptAndReturn ( outputVariable ) ;
993+ this . source += `};\n`
994+ }
995+ break ;
950996
951997 case StackOpcode . SENSING_TIMER_RESET :
952998 this . source += 'runtime.ioDevices.clock.resetProjectTimer();\n' ;
@@ -1190,7 +1236,7 @@ class JSGenerator {
11901236 * @param {string } valueJS JS code of value to return.
11911237 */
11921238 stopScriptAndReturn ( valueJS ) {
1193- if ( this . isProcedure ) {
1239+ if ( this . isProcedure || this . allowReturns ) {
11941240 this . source += `return ${ valueJS } ;\n` ;
11951241 } else {
11961242 this . retire ( ) ;
0 commit comments