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"))]
@halalbit
Copy link

Hi there ! I don't understand why do you iterate for each function of blocks , you can simply just run the first one ?

let exec (blocks: (string * (unit -> unit)) list): unit =
        match blocks with
        | [] -> ()
        | (_,foo) :: _ -> foo ()

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