How can I restart a currently-running application with AppleScript?

I've created an application with a "Run AppleScript" action in Automator.

I've created a Service in Automator which launches the aforementioned app.

The Service is triggered by a keyboard shortcut, assigned in System Preferences

The application presents a series of dialogs to the user. I would like to give the user the option of restarting the entire application mid-application. For example, suppose that the following line was Line 100 of the code:

set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})

   if buttonChoice is "Start over" then     
      <this is where I need your help, Ask Different>
   end if

When I say "restart" or "start over," I mean that I want to return the user to the initial dialog of the application, that is, the very first line of code of the application.

Can this be done using AppleScript?

If needed, this is the location of the application file:

/Applications/My Applications/My Log.app


The following code example assume that the Run AppleScript action starts with an on run command without any list, e.g. {input, parameters} and consequently ends the script with end run:

on run

    (*
            This comment represents the e.g. previous 99 lines of code.
        *)

    set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})
    try
        if buttonChoice is "Start over" then
            return on run
        end if
    end try

    (*
            This comment represents the rest of the code in the script.
        *)

end run

Note that I tested this in macOS Sierra 10.12 and while it does appear to start over, because if you press the "Start over" button it loops until you select another choice, I'm not sure this is the best way to implement this. I say that because I do not know the structure and coding of the rest of the script and that may make a difference along with the fact that while testing other code on each side of this, I was able to crash the app depending on what was going on if I looped more then once at this point.

So with that said, I'm offering this as something to test throughly before implementing it in the final code.

I'd suggest just allowing the user to terminate the app with a message to manually restart by pressing the key-combo to trigger the service that starts the app over implementing a loop such as this.


Update:

I began with user3439894's solution as my base, but I had to make a couple of modifications to perfect the "restart" feature for my application (as user3439894 recommended).

At first, when I directly copied the solution, I was having an issue where the code would run one extra time after the restarted run completed. But, by trial and error, I managed to intuit a solution.

Here's what I did to get it to work:

I put the following line before the very first line of the main body of my code:

try

and at the end of my main body of code, I put:

on error errStr number errorNumber
end try

As instructed by user3439894, I also had to delete the default return input line from this location (and I had no need to return input in this application, anyway).

Then, after every dialog of which I wanted the user to be presented with the option to start over in that dialog, I put:

if buttonChoice is "Start over" then
    return on run
end if

Following these steps, the "restart" function works perfectly! It doesn't repeat an extra number of times at the end, nor does it ever present the user with some error. I can also loop the application multiple times, if I so desire, without error or issue.

It even works perfectly when the dialogs are located in subroutines. Note that my subroutines are not within the try block.


What happens when you need to use input in your AppleScript?

I managed to discover a workaround. Simply place the restart code within a subroutine:

on run {input, parameters}
    restartSubroutine()
    return input
end run

on restartSubroutine()
    set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})

    try
        if buttonChoice is "Start over" then
            return on run restartSubroutine()
            (*
            The following lines work as well:
            return on restartSubroutine()
            return run restartSubroutine()
            *)
        end if
    end try
end restartSubroutine

Of course, the restart function will only take you back to the beginning of that subroutine, not to the first line of the main body. But, if you don't need to reference the input until the end of your script, this may work for you so that you can have a functional restart button right up until the moment that you need input.


Edit:

I just figured out an even better workaround:

on run {input, parameters}
    restartSubroutine(input)
    return input
end run

on restartSubroutine(input)
    set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})

    if buttonChoice is "Start over" then
        return restartSubroutine(input)
    end if      
end restartSubroutine

If you send the input to a subroutine, then you can have a restart function all while having access to the input contents. Win-win.