<p>Suppose I am writing a <a href="https://en.wikipedia.org/wiki/Source-to-source_compiler" rel="nofollow noreferrer">source-to-source compiler</a> (also called a transpiler) from one high-level imperative language to another, where the source language allows <a href="https://en.wikipedia.org/wiki/Label_(computer_science)" rel="nofollow noreferrer">labelled statements</a> to be targeted by <code>break</code> and <code>continue</code>, while the target language doesn't. For example, from Javascript to Python.</p>
<p>Manual translation is possible by inserting a flag variable, but there may be many other places besides the loop conditions where this flag will need to be checked, so it is not as simple as just including the flag in the loop condition. For example:</p>
<pre class="lang-js prettyprint-override"><code>// Javascript code
outer:
while(cond1) {
    foo();
    while(cond2) {
        bar();
        if(cond3) {
            break outer;
        }
        baz();
    }
    qux();
}
</code></pre>
<pre class="lang-py prettyprint-override"><code># Translated Python code
flag = True
while flag and cond1:
    foo()
    while flag and cond2:
        bar()
        if cond3:
            flag = False
        if flag:
            baz()
    if flag:
        qux()
</code></pre>
<p>How can a program transformation like the above be done automatically ─ either by inserting a flag variable or otherwise? Answers which make use of single-level <code>break</code>/<code>continue</code> in the target language are fine, but answers which can eliminate <code>break</code>/<code>continue</code> entirely are even better.</p>
<p>Ideally I would like to preserve the original code structure as much as possible, so e.g. replacing the whole outer loop with a loop-and-switch state machine is not a preferred solution.</p>
<hr />
<p>This question is distinct from <a href="https://languagedesign.stackexchange.com/q/606/89">What are the different options for breaking out of an inner loop?</a> as that question is about alternatives to labelled <code>break</code> and <code>continue</code> when designing a language, whereas this question is about how to transpile between existing languages.</p>

<compilers><control-flow><transpilers><high-level-languages><program-transformation>
How to transpile labelled break/continue statements to a high-level language which lacks them?
<p>A simple solution would be to extract the (outer) loop into a function and return early. The function could take all variables that the loops needs as parameters. If it needs to modify any of the variables it can take pointers or references to them, or, if your target language does not support those, return the modified value and assign that to the original variable.</p>
<p>Your example would result in the following code:</p>
<pre class="lang-python prettyprint-override"><code>mutated_variable = ...

def outer(mutated_var):
    while cond1:
        foo()
        while cond2:
            bar()
            # mutated_var is passed as a parameter, 
            # mutated and returned
            mutated_var += 1 
            if cond3:
                return mutated_var
            baz()
        qux()
    return mutated_var

mutated_variable = outer(mutated_variable)
</code></pre>
<p>Only if your target language does not support mutating references or multiple return values this approach won't work when multiple variables are mutated in the loop. But then you can still group them in a struct or similar.</p>

CC BY-SA 4.0
2023-05-22T17:08:08.390Z
2023-05-24T15:47:28.533Z
2023-05-24T15:47:28.533Z
chrysante
CC BY-SA 4.0
2023-05-22T17:47:32.607Z
I have no idea if this is idiomatic or even correct python, but I hope it gets the point across
chrysante
CC BY-SA 4.0
2023-05-22T18:01:14.933Z
To mutate variables, closures or inner functions could be used
Seggan
CC BY-SA 4.0
2023-05-24T15:48:24.030Z
Given the clarification, this is a good answer, since it does work fine for many target languages (particularly in Python, the `nonlocal` keyword is enough to modify variables from the outer scope), and it doesn't change the structure of the code very much.
kaya3
CC BY-SA 4.0
2023-08-08T12:06:41.140Z
This works well for `break`... but what about `continue`?
Matthieu M.
CC BY-SA 4.0
2023-08-08T15:38:15.723Z
@MatthieuM. For continue you would extract the body of the outer loop into a function and return early. It is a good point though because for a loop that has both break and continue statements this solution breaks down and you would have to resort to flags.
chrysante
<p>One possible transpilation, if the language supports exceptions, is to rely on those, producing:</p>
<pre class="lang-python prettyprint-override"><code>class BreakOuter(BaseException):pass
try: 
   while cond1:
      foo()
      while cond2:
         bar()
         if cond3:
             raise BreakOuter()
         baz()
except BreakOuter:
    pass
</code></pre>
<p>This, while a bit verbose, has the advantage that code only needs to get added in one place (the outer loop at the end of the break), making transpilation only require replacing that while loop with a verbose but constant bit of boilerplate and no analysis of the code inside the loop.</p>
<p>For a multi-level <code>continue</code>, you swap the order of the <code>try</code> and the outer <code>while</code> loop.</p>
<pre class="lang-python prettyprint-override"><code>while cond1:
   try: 
      ...
   except ContinueOuter:
     pass
</code></pre>
<p>If the base code has multiple nested breaks, then they can use different exception classes for each label.</p>

CC BY-SA 4.0
2023-05-21T16:32:45.163Z
2023-05-21T16:32:45.163Z
pppery
CC BY-SA 4.0
2023-05-21T19:40:07.510Z
This would work but throwing and catching exceptions is usually quite slow, I don't really see what benefit this would have over the flag setting approach. Still +1 for the novel idea
mousetail 'he-him'
CC BY-SA 4.0
2023-05-24T19:19:30.720Z
One upside of this approach is that it barely changes the structure of the code. Python in particular also uses exceptions to terminate `for` loops, because iterators are supposed to throw `StopIteration` to signal when they have no more elements; so the performance implications in Python aren't that significant.
kaya3
CC BY-SA 4.0
2023-08-05T14:38:39.750Z
@mousetail - the performance varies depending on the language implementation.  The question asked about both Javascript and Python, and while I wouldn't recommend this for Javascript as most JS virtual machines aren't optimized for it, CPython and most other Python implementations have very fast exception handling, so it would be sensible to use it there.
occipita
<p>If your target language lacks labelled breaks but has <code>goto</code> (for example, if the target language is C), you could transpile loops of this form:</p>
<pre class="lang-swift prettyprint-override"><code>outer: while cond {
  ...
}
</code></pre>
<p>to loops of this form:</p>
<pre class="lang-c prettyprint-override"><code>while (cond) {
  ...
  continue_outer:
}
break_outer:
</code></pre>
<p>Then, <code>continue outer</code> and <code>break outer</code> become <code>goto continue_outer</code> and <code>goto break_outer</code> respectively. Depending on your target language, you may have to be careful not to generate two labels of the same name in the same file.</p>

CC BY-SA 4.0
2023-05-21T15:27:30.013Z
2023-05-21T15:40:49.770Z
2023-05-21T15:40:49.770Z
Bbrk24
CC BY-SA 4.0
2023-05-21T15:28:27.913Z
Do any languages exist that lack labeled break but do have goto? Good answer otherwise
mousetail 'he-him'
CC BY-SA 4.0
2023-05-21T15:29:31.827Z
C and its immediate family don't have labelled break.
Bbrk24
CC BY-SA 4.0
2023-05-24T16:40:51.607Z
@mousetail APL has goto but no labelled break.
Adám
<p>Here's a method using unlabelled <code>break</code>/<code>continue</code>. I'll use slightly different JS code:</p>
<pre><code>outer:
while (cond) {
    foo();
    inner:
    while (cond) {
        bar();
        while (cond) {
            if (cond) {
                break outer;
            } else if (cond) {
                continue inner;
            }
        }
        if (cond) break;
    }
    baz();
}
</code></pre>
<p>The idea is, rather than using just a boolean flag, to include enough information to fully describe what you're doing with which loop.</p>
<ol>
<li>Construct a map <code>labelDepths</code> from labels to their loops’ nesting depth. In this example, if the translator is written in JS, our map might be the object <code>{&quot;outer&quot;: 0, &quot;inner&quot;: 1}</code>.</li>
<li>Within each function declaration in the output, write two local variable declarations (with unique names), e.g. <code>depth=0</code> and <code>action=None</code>. These will control, respectively, <code>break</code>/<code>continue</code> propagation and which action to take at the end of propagation.</li>
<li>For each labelled <code>break</code>/<code>continue</code> statement in the input, replace the statement in the output with <code>depth=_D_; action=_A_; break</code>, where <code>_D_</code> is the value of <code>labelDepths[label]</code> and <code>_A_</code> is either <code>&quot;break&quot;</code> or <code>&quot;continue&quot;</code>. For example, <code>break inner;</code> would become <code>depth=1;action=&quot;continue&quot;;break</code>. Write unlabelled <code>break</code>/<code>continue</code> statements to the output normally.</li>
<li>For each loop statement with depth greater than 0, append the following as the next sibling of the loop statement, replacing <code>_D_</code> with <code>(the depth of the loop) - 1</code>:</li>
</ol>
<pre><code>if action != None:
    if depth &lt; _D_:
        break
    if action == &quot;continue&quot;:
        action = None
        continue
    action = None
    break
</code></pre>
<p>Our JS example then ends up as the following Python code:</p>
<pre><code>action = None
depth = 0

# outer:
while cond: # depth = 0
    foo()
    # inner:
    while cond: # depth = 1
        bar()
        while cond: # depth = 2
            if cond:
                # break outer
                depth=0;action=&quot;break&quot;;break
            elif cond:
                # continue inner
                depth=1;action=&quot;continue&quot;;break
        if action != None:
            if depth &lt; 1:
                break
            if action == &quot;continue&quot;:
                action = None
                continue
            action = None
            break
        if cond:
            break
    if action != None:
        if depth &lt; 0:
            break
        if action == &quot;continue&quot;:
            action = None
            continue
        action = None
        break
    baz()
</code></pre>
<p>There are a few ways we could make the output more efficient, such as using integers for the action constants or only including propagation code after loops that transitively contain labelled <code>break</code>/<code>continue</code> statements, but hopefully this gives you the basic idea.</p>

CC BY-SA 4.0
2023-05-22T07:15:43.773Z
2023-05-22T07:15:43.773Z
Brandon Dyck
CC BY-SA 4.0
2023-05-22T07:20:13.623Z
This results in output code that is a bit more verbose than you'd get by hand, but it has the advantage that it doesn't require transforming any other kinds of statement than the loops, `break` and `continue` statements themselves. Nice one! (also welcome!)
kaya3
CC BY-SA 4.0
2023-05-22T07:34:39.400Z
@kaya3 Thanks! I figure a little extra verbosity isn't a big deal in translated code. If you're worried about readability, though, it would probably help to add some simple comments to the output.
Brandon Dyck
CC BY-SA 4.0
2023-05-22T07:35:10.063Z
Readability isn't super-important, just one consideration among many.
kaya3
# How to transpile labelled break/continue statements to a high-level language which lacks them?
Posted by: username_0 on 2023-05-21
Suppose I am writing a source-to-source compiler (also called a transpiler) from one high-level imperative language to another, where the source language allows labelled statements to be targeted by break and continue, while the target language doesn't. For example, from Javascript to Python.
Manual translation is possible by inserting a flag variable, but there may be many other places besides the loop conditions where this flag will need to be checked, so it is not as simple as just including the flag in the loop condition. For example:
// Javascript code
outer:
while(cond1) {
    foo();
    while(cond2) {
        bar();
        if(cond3) {
            break outer;
        }
        baz();
    }
    qux();
}

# Translated Python code
flag = True
while flag and cond1:
    foo()
    while flag and cond2:
        bar()
        if cond3:
            flag = False
        if flag:
            baz()
    if flag:
        qux()

How can a program transformation like the above be done automatically ─ either by inserting a flag variable or otherwise? Answers which make use of single-level break/continue in the target language are fine, but answers which can eliminate break/continue entirely are even better.
Ideally I would like to preserve the original code structure as much as possible, so e.g. replacing the whole outer loop with a loop-and-switch state machine is not a preferred solution.

This question is distinct from What are the different options for breaking out of an inner loop? as that question is about alternatives to labelled break and continue when designing a language, whereas this question is about how to transpile between existing languages.
**Tags:** compilers control-flow transpilers high-level-languages program-transformation
---
## 4 answers
### Answer by username_9 on 2023-05-22. Score: 8 | Accepted answer
Here's a method using unlabelled break/continue. I'll use slightly different JS code:
outer:
while (cond) {
    foo();
    inner:
    while (cond) {
        bar();
        while (cond) {
            if (cond) {
                break outer;
            } else if (cond) {
                continue inner;
            }
        }
        if (cond) break;
    }
    baz();
}

The idea is, rather than using just a boolean flag, to include enough information to fully describe what you're doing with which loop.

Construct a map labelDepths from labels to their loops’ nesting depth. In this example, if the translator is written in JS, our map might be the object {"outer": 0, "inner": 1}.
Within each function declaration in the output, write two local variable declarations (with unique names), e.g. depth=0 and action=None. These will control, respectively, break/continue propagation and which action to take at the end of propagation.
For each labelled break/continue statement in the input, replace the statement in the output with depth=_D_; action=_A_; break, where _D_ is the value of labelDepths[label] and _A_ is either "break" or "continue". For example, break inner; would become depth=1;action="continue";break. Write unlabelled break/continue statements to the output normally.
For each loop statement with depth greater than 0, append the following as the next sibling of the loop statement, replacing _D_ with (the depth of the loop) - 1:

if action != None:
    if depth < _D_:
        break
    if action == "continue":
        action = None
        continue
    action = None
    break

Our JS example then ends up as the following Python code:
action = None
depth = 0

# outer:
while cond: # depth = 0
    foo()
    # inner:
    while cond: # depth = 1
        bar()
        while cond: # depth = 2
            if cond:
                # break outer
                depth=0;action="break";break
            elif cond:
                # continue inner
                depth=1;action="continue";break
        if action != None:
            if depth < 1:
                break
            if action == "continue":
                action = None
                continue
            action = None
            break
        if cond:
            break
    if action != None:
        if depth < 0:
            break
        if action == "continue":
            action = None
            continue
        action = None
        break
    baz()

There are a few ways we could make the output more efficient, such as using integers for the action constants or only including propagation code after loops that transitively contain labelled break/continue statements, but hopefully this gives you the basic idea.
> **Comments:**
> **username_0** (2023-05-22): This results in output code that is a bit more verbose than you'd get by hand, but it has the advantage that it doesn't require transforming any other kinds of statement than the loops, `break` and `continue` statements themselves. Nice one! (also welcome!)  
> **username_9** (2023-05-22): @kaya3 Thanks! I figure a little extra verbosity isn't a big deal in translated code. If you're worried about readability, though, it would probably help to add some simple comments to the output.  
> **username_0** (2023-05-22): Readability isn't super-important, just one consideration among many.  
---
### Answer by username_4 on 2023-05-21. Score: 8
One possible transpilation, if the language supports exceptions, is to rely on those, producing:
class BreakOuter(BaseException):pass
try: 
   while cond1:
      foo()
      while cond2:
         bar()
         if cond3:
             raise BreakOuter()
         baz()
except BreakOuter:
    pass

This, while a bit verbose, has the advantage that code only needs to get added in one place (the outer loop at the end of the break), making transpilation only require replacing that while loop with a verbose but constant bit of boilerplate and no analysis of the code inside the loop.
For a multi-level continue, you swap the order of the try and the outer while loop.
while cond1:
   try: 
      ...
   except ContinueOuter:
     pass

If the base code has multiple nested breaks, then they can use different exception classes for each label.
> **Comments:**
> **username_5** (2023-05-21): This would work but throwing and catching exceptions is usually quite slow, I don't really see what benefit this would have over the flag setting approach. Still +1 for the novel idea  
> **username_0** (2023-05-24): One upside of this approach is that it barely changes the structure of the code. Python in particular also uses exceptions to terminate `for` loops, because iterators are supposed to throw `StopIteration` to signal when they have no more elements; so the performance implications in Python aren't that significant.  
> **username_6** (2023-08-05): @mousetail - the performance varies depending on the language implementation.  The question asked about both Javascript and Python, and while I wouldn't recommend this for Javascript as most JS virtual machines aren't optimized for it, CPython and most other Python implementations have very fast exception handling, so it would be sensible to use it there.  
---
### Answer by username_1 on 2023-05-22. Score: 5
A simple solution would be to extract the (outer) loop into a function and return early. The function could take all variables that the loops needs as parameters. If it needs to modify any of the variables it can take pointers or references to them, or, if your target language does not support those, return the modified value and assign that to the original variable.
Your example would result in the following code:
mutated_variable = ...

def outer(mutated_var):
    while cond1:
        foo()
        while cond2:
            bar()
            # mutated_var is passed as a parameter, 
            # mutated and returned
            mutated_var += 1 
            if cond3:
                return mutated_var
            baz()
        qux()
    return mutated_var

mutated_variable = outer(mutated_variable)

Only if your target language does not support mutating references or multiple return values this approach won't work when multiple variables are mutated in the loop. But then you can still group them in a struct or similar.
> **Comments:**
> **username_1** (2023-05-22): I have no idea if this is idiomatic or even correct python, but I hope it gets the point across  
> **username_2** (2023-05-22): To mutate variables, closures or inner functions could be used  
> **username_0** (2023-05-24): Given the clarification, this is a good answer, since it does work fine for many target languages (particularly in Python, the `nonlocal` keyword is enough to modify variables from the outer scope), and it doesn't change the structure of the code very much.  
> **username_3** (2023-08-08): This works well for `break`... but what about `continue`?  
> **username_1** (2023-08-08): @MatthieuM. For continue you would extract the body of the outer loop into a function and return early. It is a good point though because for a loop that has both break and continue statements this solution breaks down and you would have to resort to flags.  
---
### Answer by username_7 on 2023-05-21. Score: 2
If your target language lacks labelled breaks but has goto (for example, if the target language is C), you could transpile loops of this form:
outer: while cond {
  ...
}

to loops of this form:
while (cond) {
  ...
  continue_outer:
}
break_outer:

Then, continue outer and break outer become goto continue_outer and goto break_outer respectively. Depending on your target language, you may have to be careful not to generate two labels of the same name in the same file.
> **Comments:**
> **username_5** (2023-05-21): Do any languages exist that lack labeled break but do have goto? Good answer otherwise  
> **username_7** (2023-05-21): C and its immediate family don't have labelled break.  
> **username_8** (2023-05-24): @mousetail APL has goto but no labelled break.  
---
