Control Flow Operators ====================== Sequence, Test, Yield, and Parallelism -------------------------------------- ### sequence ### Sequences are implicit in HipHop. That is, two statements separated by a `;` are executed sequentially. ### pragma ### [Formal syntax](../syntax/hiphop.bnf#HHYield) The `pragma` form executes a JavaScript statement during the reaction. Example: [seq.hh.js](../../test/seq.hh.js) The JavaScript body may have signal dependencies. Example: [atom-dep-par.hh.js](../../test/atom-dep-par.hh.js) > [!CAUTION] > Under no circumstances JavaScript side effects must be observable > from within a HipHop reaction. It is the responsability of the > JavaScript program not to execute visible side effects. If such > a side effect happen and is observed from within a HipHop reaction, > its behavior becomes unpredictable. ### if (delay) { block } [else { block }] ### Execute the _then_ block is delay is true, execute the optional _else_ block otherwise. The `delay` [expression](../syntax/hiphop.bnf#HHDelay) can any JavaScript that evaluates to a boolean. If that expression uses signal attributes (`now`, `pre`, `nowval`, or `preval`), HipHop computes a flow dependency in order to evalute the `delay` only when all the values of these attributes are known. For instance, the test: ``` if (!SIG.now) { ... } ``` depends on the `now` attribute of the signal `SIG`. It cannot be evaluated before it is know that `SIG` is emitted during the reaction or not. The HipHop runtime system computes these dependencies automatically. A value of a signal can also be checked. For instance: ```hiphop if(SIG.nowval > 10 && SIG.nowval < 100) { pragma { console.log("signal in range") } } ``` See [staging](../staging.md) for using dynamic signal names in delay expressions. Example: [if1.hh.js](../../test/if1.hh.js) ### yield ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHYield) A thread of execution can suspend itself for the current instance using the `yield` construct. The execution will resume after the `yield` when the `react` method of the machine will be called again. Example: [weak.hh.js](../../test/weak.hh.js) Example: [trap-par-3.hh.js](../../test/trap-par-3.hh.js) ### fork { ... } par { ... } ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHFork) Run all the bodies in parallel. Complete when all bodies have completed. A body completes because it has executed all its statements or because it has exited using `break`. Example: [parallel-unary.hh.js](../../test/parallel-unary.hh.js) This example uses two nested `fork` constructs. The second is synchronized with the first as it waits for an event the first branch is to emit. Example: [trap-loop-2.hh.js](../../test/trap-loop-2.hh.js) This second example uses a label and a `break` to terminate a parallel branch. ### halt ### Block infinitly the current thread. Keep in mind that a blocked thread can be suspended or even aborted. Example: [run-add-par.hh.js](../../test/run-add-par.hh.js) Loop ---- Loops are so central HipHop program control flow that HipHop proposes several loop constructs, see [derived forms](#derived-forms). These are all based on a combination of the elementary `loop` construct and [lexical espaces](#lexical-escapes). ### loop { ... } ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHLoop) This is the basis loop construct that implements an infinite loop Example: [sync1.hh.js](../../test/sync1.hh.js) A loop can be interrupted by exiting with a `break` statement. Example: [trap-loop.hh.js](../../test/trap-loop.hh.js) > [!NOTE] > It is not permitted to implement _instantaneous_ loops, that is > a loop for which two iterations may execute during the same reaction. > This will be rejected by the compiler. All loops must have a `yield` > statement in their control flow. Suspension ---------- ### suspend delay { block } ### Suspend the execution of `block` while `delay` is true. Example: [suspend.hh.js](../../test/suspend.hh.js) Example: [trap-suspend.hh.js](../../test/trap-suspend.hh.js) Lexical Escapes --------------- HipHop supports an escape mechanism by the means for the `exit`/`break` constructs. They enable a program to abort an ongoing computation. ### lbl ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHExit) An _exit_ is syntactically similar to a JavaScript label. it must be followed by a HipHop statement. This statement can be interrupted by _breaking_ to that exit form. ### break lbl ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHBreak) Abort the execution of the current statement and continue the execution after the statement that follows that break label. The `break` form can be used to abord an execution thread when used to escape a `fork`/`par` form. Example: [timeout.hh.js](../../test/timeout.hh.js) This example shows how to exit a `loop`. Example: [trap-par.hh.js](../../test/trap-par.hh.js) This example shows how to exit a `fork`/`par`. Example: [trap-await-parallel.hh.js](../../test/trap-await-parallel.hh.js) This example shows that several threads can decide to exit from a `fork`/`par`. Example: [p18.hh.js](../../test/p18.hh.js) Derived Forms ------------- ### every delay { ... } ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHEvery) A loop executed each time the `delay` is true. Abort the execution of the body when `delay` is true. Delays are documented [here](./signal#test-await-and-emit). Example: [every1.hh.js](../../test/every1.hh.js) All the delay forms can be used with `every`. Example: [every-delay.hh.js](../../test/every-delay.hh.js) The form `every` is a derived form. The form: ```javascript every (expr) { ... body ... } ``` is equivalent to: ```javascript await (expr); loop { continue: fork { ... body ... } par { await (expr); break continue; } } ``` ### do { ... } every delay ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHDo) Execute the `do`'s body and loop when `test` is true. Example: [loopeach.hh.js](../../test/loopeach.hh.js) The form `do`/`every` is a dericed form. The form: ```javascript do { ... } every (expr); ``` is equivalent to: ```javascript loop { ... body ... await (expr); } ``` ### abort delay { ... } ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHAbort) Execute the `abort`'s body and abort the execution when delay is true. Example: [abort-par.hh.js](../../test/abort-par.hh.js) Example: [abortpre.hh.js](../../test/abortpre.hh.js) The form: ```javascript abort (expr) { ... body ... } ``` is equivalent to ```javascript exit: fork { ... body ... } par { await (expr); break exit; } ``` ### weakabort delay { ... } ### ☆ [Formal syntax](../syntax/hiphop.bnf#HHAbort) Execute the `weakabort`'s body and abort the execution when delay is true at the end of the reaction Example: [loopeach-weakabort-emit.hh.js](../../test/loopeach-weakabort-emit.hh.js) Example: [weak2.hh.js](../../test/weak2.hh.js) Example: [weak-immediate.hh.js](../../test/weak-immediate.hh.js) The form: ```javascript abort (expr) { ... body ... } ``` is equivalent to ```javascript exit: fork { ... body ... } par { await (expr); break exit; } ``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [[main page]](../../README.md) | [[documentation]](../README.md) | [[language]](./README.md) | [[license]](../license.md)