Skip to content

Instantly share code, notes, and snippets.

@rexim
Created June 15, 2023 16:52
Show Gist options
  • Save rexim/f9115cf09b3467cd3581862fda58cc42 to your computer and use it in GitHub Desktop.
Save rexim/f9115cf09b3467cd3581862fda58cc42 to your computer and use it in GitHub Desktop.
open Printf
exception Goto of string
let label (name: string) = ()
let goto (name: string) = raise (Goto name)
let goto_block (blocks: (string * (unit -> unit)) list): unit =
let rec goto_block_impl (name: string option): unit =
try
let exec (blocks: (string * (unit -> unit)) list): unit =
blocks |> List.iter (fun (_, block) -> block ())
in
let rec skip (blocks: (string * (unit -> unit)) list) (entry: string) =
match blocks with
| [] -> ()
| (name, _) :: rest ->
if String.equal name entry
then exec blocks
else skip rest entry
in
match name with
| None -> exec blocks
| (Some entry) -> skip blocks entry
with
Goto name -> goto_block_impl (Some name)
in goto_block_impl None
let () =
let i = ref 0 in
goto_block
[("loop", (fun () ->
if !i >= 10 then goto "out" else ();
printf "%d: Hello, World\n" !i;
i := !i + 1;
goto "loop"));
("out", (fun () ->
printf "Done!\n"))]
@jpmassari
Copy link

jpmassari commented Dec 6, 2023

Guys, I tested a for loop of an object inside a block, and a normal function with a for loop. Any idea why the loop inside the goto_block mechanism always much faster?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment