From e7427d1108d31335468f35eccb3ecdcc39488de4 Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 12:18:11 -0400 Subject: [PATCH 01/11] add Lexa --- .github/workflows/system_lexa.yml | 37 +++++++ Makefile | 12 +++ README.md | 1 + benchmarks/lexa/Makefile | 42 ++++++++ benchmarks/lexa/countdown/main.lx | 35 +++++++ benchmarks/lexa/fibonacci_recursive/main.lx | 12 +++ benchmarks/lexa/iterator/main.lx | 30 ++++++ benchmarks/lexa/nqueens/main.lx | 56 ++++++++++ benchmarks/lexa/parsing_dollars/main.lx | 109 ++++++++++++++++++++ benchmarks/lexa/product_early/main.lx | 51 +++++++++ benchmarks/lexa/resume_nontail/main.lx | 39 +++++++ benchmarks/lexa/tree_explore/main.lx | 95 +++++++++++++++++ benchmarks/lexa/triples/main.lx | 50 +++++++++ systems/lexa/Dockerfile | 19 ++++ 14 files changed, 588 insertions(+) create mode 100644 .github/workflows/system_lexa.yml create mode 100644 benchmarks/lexa/Makefile create mode 100644 benchmarks/lexa/countdown/main.lx create mode 100644 benchmarks/lexa/fibonacci_recursive/main.lx create mode 100644 benchmarks/lexa/iterator/main.lx create mode 100644 benchmarks/lexa/nqueens/main.lx create mode 100644 benchmarks/lexa/parsing_dollars/main.lx create mode 100644 benchmarks/lexa/product_early/main.lx create mode 100644 benchmarks/lexa/resume_nontail/main.lx create mode 100644 benchmarks/lexa/tree_explore/main.lx create mode 100644 benchmarks/lexa/triples/main.lx create mode 100644 systems/lexa/Dockerfile diff --git a/.github/workflows/system_lexa.yml b/.github/workflows/system_lexa.yml new file mode 100644 index 0000000..c640252 --- /dev/null +++ b/.github/workflows/system_lexa.yml @@ -0,0 +1,37 @@ +name: Lexa + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + pull_request: + branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +#From https://docs.github.com/en/actions/guides/publishing-docker-images +jobs: + bench-system-lexa: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - uses: satackey/action-docker-layer-caching@v0.0.11 + # Ignore the failure of a step and avoid terminating the job. + continue-on-error: true + + - name: Add write permission to directories + run: | + find . -type d -exec chmod 777 {} \; + + - name: Test Lexa system + run: | + make test_lexa + diff --git a/Makefile b/Makefile index 9bd3e26..dcd945b 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,18 @@ test_koka: system_koka docker run -v $(shell pwd):/source $(DOCKERHUB):koka \ make -C /source/benchmarks/koka test +# Lexa +system_lexa: + docker build -t $(DOCKERHUB):lexa systems/lexa + +bench_lexa: system_lexa + docker run -it --init -v $(shell pwd):/source $(DOCKERHUB):lexa \ + make -C /source/benchmarks/lexa + +test_lexa: system_lexa + docker run -v $(shell pwd):/source $(DOCKERHUB):lexa \ + make -C /source/benchmarks/lexa test + # libmpeff system_libmpeff: system_base docker build -t $(DOCKERHUB):libmpeff systems/libmpeff diff --git a/README.md b/README.md index 2cde945..9023fbd 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ contains the results of running the OCaml benchmarks. | [Effekt](https://github.com/effekt-lang/effekt) | [![Effekt](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_effekt.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_effekt.yml) | | [Handlers in Action](https://github.com/slindley/effect-handlers) | [![Handlers in Action](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml) | | [Koka](https://github.com/koka-lang/koka) | [![Koka](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_koka.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_koka.yml) | +| [Lexa](https://github.com/lexa-lang/lexa) | [![Lexa](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_lexa.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_lexa.yml) | | [libhandler](https://github.com/koka-lang/libhandler) | [![libhandler](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libhandler.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libhandler.yml) | | [libmpeff](https://github.com/koka-lang/libmprompt) | [![libmpeff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libmpeff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libmpeff.yml) | | [libseff](https://github.com/effect-handlers/libseff.git) | [![libseff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml) | diff --git a/benchmarks/lexa/Makefile b/benchmarks/lexa/Makefile new file mode 100644 index 0000000..dd82cda --- /dev/null +++ b/benchmarks/lexa/Makefile @@ -0,0 +1,42 @@ +bench: build + hyperfine --export-csv results.csv \ + 'countdown/main 200000000' \ + 'fibonacci_recursive/main 42' \ + 'product_early/main 100000' \ + 'iterator/main 40000000' \ + 'nqueens/main 12' \ + 'tree_explore/main 16' \ + 'triples/main 300' \ + 'parsing_dollars/main 20000' \ + 'resume_nontail/main 20000' + +test: build + cd countdown ; ./main 5 > actual ; echo 0 > expected ; diff expected actual + cd fibonacci_recursive ; ./main 5 > actual ; echo 5 > expected ; diff expected actual + cd product_early ; ./main 5 > actual ; echo 0 > expected ; diff expected actual + cd iterator ; ./main 5 > actual ; echo 15 > expected ; diff expected actual + cd nqueens ; ./main 5 > actual ; echo 10 > expected ; diff expected actual + cd tree_explore ; ./main 5 > actual ; echo 946 > expected ; diff expected actual + cd triples ; ./main 10 > actual ; echo 779312 > expected ; diff expected actual + cd parsing_dollars ; ./main 10 > actual ; echo 55 > expected ; diff expected actual + cd resume_nontail ; ./main 5 > actual ; echo 37 > expected ; diff expected actual + +build: + cd countdown ; lexa main.lx -o main + cd fibonacci_recursive ; lexa main.lx -o main + cd product_early ; lexa main.lx -o main + cd iterator ; lexa main.lx -o main + cd nqueens ; lexa main.lx -o main + cd tree_explore ; lexa main.lx -o main + cd triples ; lexa main.lx -o main + cd parsing_dollars ; lexa main.lx -o main + cd resume_nontail ; lexa main.lx -o main + +clean: + -rm */clue_table.txt + -rm */main.c + -rm */offset_functions.h + -rm */main + -rm results.csv + -rm */expected + -rm */actual diff --git a/benchmarks/lexa/countdown/main.lx b/benchmarks/lexa/countdown/main.lx new file mode 100644 index 0000000..34d1931 --- /dev/null +++ b/benchmarks/lexa/countdown/main.lx @@ -0,0 +1,35 @@ +effect State { + get: () -> int + set: (int) -> unit +} + +def countdown [; state_stub: State] (): int { + val i = raise state_stub.get(); + if i == 0 then + i + else ( + raise state_stub.set(i-1); + countdown:[; state_stub]() + ) +} + +def run(n: int): int { + val s = newref {n}; + handle <> { + countdown:[; state_stub]() + } with state_stub: State { + def get() { + s[0] + } + + def set(i) { + s[0] := i; + 0 + } + } +} + +def main(): int { + ~printInt(run(~readInt())); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/fibonacci_recursive/main.lx b/benchmarks/lexa/fibonacci_recursive/main.lx new file mode 100644 index 0000000..c96bbed --- /dev/null +++ b/benchmarks/lexa/fibonacci_recursive/main.lx @@ -0,0 +1,12 @@ +def fib(n: int): int { + if n == 0 then 0 else + if n == 1 then 1 else + fib(n - 1) + fib(n - 2) +} + +def main(): int { + val arg = ~readInt(); + val res = fib(arg); + ~printInt(res); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/iterator/main.lx b/benchmarks/lexa/iterator/main.lx new file mode 100644 index 0000000..719fe01 --- /dev/null +++ b/benchmarks/lexa/iterator/main.lx @@ -0,0 +1,30 @@ +effect Emit { + emit: (int) -> unit +} + +def range [; emit_stub: Emit] (l: int, u: int): int { + if l > u then + 0 + else ( + raise emit_stub.emit(l); + range:[; emit_stub](l + 1, u) + ) +} + +def run(n: int): int { + val s = newref {0}; + handle <> { + range:[; emit_stub](0, n) + } with emit_stub: Emit { + def emit(e) { + s[0] := s[0] + e; + 0 + } + }; + s[0] +} + +def main(): int { + ~printInt(run(~readInt())); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/nqueens/main.lx b/benchmarks/lexa/nqueens/main.lx new file mode 100644 index 0000000..c2964b7 --- /dev/null +++ b/benchmarks/lexa/nqueens/main.lx @@ -0,0 +1,56 @@ +effect Search { + pick: (int) -> int + fail: () -> int +} + +def safe(queen: int, diag: int, xs: node_t::[int]): bool { + val is_empty = ~listIsEmpty::[int](xs); + if is_empty then + true + else + val q = ~listHead::[int](xs); + val qs = ~listTail::[int](xs); + if queen != q && queen != q + diag && queen != q - diag then + safe(queen, diag + 1, qs) + else + false +} + +def place [; search_stub: Search] (size: int, column: int): node_t::[int] { + if column == 0 then + ~listEnd::[int]() + else + val rest = place:[; search_stub](size, column - 1); + val next = raise search_stub.pick(size); + if safe(next, 1, rest) then + ~listNode::[int](next, rest) + else + (raise search_stub.fail(); + ~listEnd::[int]()) +} + +def run(n: int): int { + handle <> { + place:[; search_stub](n, n); + 1 + } with search_stub: Search { + exc fail() { 0 } + hdl_s pick(size, k) { + loop(1, 0, size, k) + } + } +} + +def loop(i: int, a: int, size: int, k: cont <> int -> int): int { + if i == size then + a + resume_final k i + else + loop(i + 1, a + resume k i, size, k) +} + +def main(): int { + val n = ~readInt(); + val run_res = run(n); + ~printInt(run_res); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/parsing_dollars/main.lx b/benchmarks/lexa/parsing_dollars/main.lx new file mode 100644 index 0000000..3313daf --- /dev/null +++ b/benchmarks/lexa/parsing_dollars/main.lx @@ -0,0 +1,109 @@ +effect Read { + read: () -> int +} + +effect Emit { + emit: (int) -> unit +} + +effect Stop { + stop: () -> int +} + +def newline(): int { + 10 +} + +def is_newline(c: int): bool { + c == 10 +} + +def dollar(): int { + 36 +} + +def is_dollar(c: int): bool { + c == 36 +} + +def sum(action: <> [; emit_stub: Emit] (int) -> int, n: int): int { + val s = newref {0}; + handle <> { + action: [; emit_stub] (n) + } with emit_stub: Emit { + def emit(e) { + s[0] := s[0] + e + } + }; + s[0] +} + +def catch [; emit_stub: Emit] (action: <> [; stop_stub: Stop, emit_stub: Emit] (int) -> int, n: int): int { + handle { + action: [; stop_stub, emit_stub] (n) + } with stop_stub: Stop { + exc stop() { 0 } + } +} + +def feed [; stop_stub: Stop, emit_stub: Emit] (n: int, action: <> [; read_stub: Read, emit_stub: Emit, stop_stub: Stop] () -> int): int { + val i_ref = newref {0}; + val j_ref = newref {0}; + handle { + action :[; read_stub, emit_stub, stop_stub] () + } + with read_stub: Read { + def read() { + val i = i_ref[0]; + val j = j_ref[0]; + if i > n then + raise stop_stub.stop() + else ( + if j == 0 then + i_ref[0] := i + 1; + j_ref[0] := i + 1; + newline() + else + (j_ref[0] := j - 1; + dollar()) + ) + } + } +} + +def parse [; read_stub: Read, emit_stub: Emit, stop_stub: Stop] (a: int): int { + val c = raise read_stub.read(); + if is_dollar(c) then + parse: [; read_stub, emit_stub, stop_stub](a + 1) + else + if is_newline(c) then + raise emit_stub.emit(a); + parse: [; read_stub, emit_stub, stop_stub](0) + else + raise stop_stub.stop() +} + +def feed_action [; read_stub: Read, emit_stub: Emit, stop_stub: Stop] (): int { + parse:[;read_stub, emit_stub, stop_stub](0) +} + +def sum_action [;emit_stub: Emit] (n: int): int { + val catch_action_i64 = catch_action; + catch:[;emit_stub] (catch_action_i64, n) +} + +def catch_action [; stop_stub: Stop, emit_stub: Emit](n: int): int { + val feed_action_i64 = feed_action; + feed:[; stop_stub, emit_stub](n, feed_action_i64) +} + +def run(n: int): int { + val sum_action_i64 = sum_action; + sum(sum_action_i64, n) +} + +def main(): int { + val n = ~readInt(); + ~printInt(run(n)); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/product_early/main.lx b/benchmarks/lexa/product_early/main.lx new file mode 100644 index 0000000..83d6eed --- /dev/null +++ b/benchmarks/lexa/product_early/main.lx @@ -0,0 +1,51 @@ + +effect Abort { + done: (int) -> int +} + +def product [; abort_stub: Abort] (xs: node_t::[int]): int { + if ~listIsEmpty::[int](xs) then + 0 + else + val y = ~listHead::[int](xs); + val ys = ~listTail::[int](xs); + if y == 0 then + raise abort_stub.done(0) + else + y * product:[; abort_stub](ys) +} + +def enumerate(i: int): node_t::[int] { + if i < 0 then + ~listEnd::[int]() + else + ~listNode::[int](i, enumerate(i - 1)) +} + +def runProduct(xs: node_t::[int]): int { + handle <> { + product:[; abort_stub](xs) + } with abort_stub: Abort { + exc done(r) { + r + } + } +} + +def loop(xs: node_t::[int], i: int, a: int): int { + if i == 0 then + a + else + loop(xs, i - 1, a + runProduct(xs)) +} + +def run(n: int): int { + loop(enumerate(1000), n, 0) +} + +def main(): int { + val arg1 = ~readInt(); + val arg2 = run(arg1); + ~printInt(arg2); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/resume_nontail/main.lx b/benchmarks/lexa/resume_nontail/main.lx new file mode 100644 index 0000000..087a373 --- /dev/null +++ b/benchmarks/lexa/resume_nontail/main.lx @@ -0,0 +1,39 @@ +effect Operator { + operator: (int) -> int +} + +def loop [;operator_stub: Operator](i: int, s: int): int { + if i == 0 then + s + else ( + raise operator_stub.operator(i); + loop: [;operator_stub](i - 1, s) + ) +} + +def run(n: int, s: int): int { + handle <> { + loop: [;operator_stub](n, s) + } with operator_stub: Operator { + hdl_1 operator(x, k) { + val y = resume_final k 0; + ~mathAbs(x - (503 * y) + 37) % 1009 + } + } +} + +def step(l: int, s: int, n: int): int { + if l == 0 then + s + else + step(l - 1, run(n, s), n) +} + +def repeat(n: int): int { + step(1000, 0, n) +} + +def main(): int { + ~printInt(repeat(~readInt())); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/tree_explore/main.lx b/benchmarks/lexa/tree_explore/main.lx new file mode 100644 index 0000000..0733695 --- /dev/null +++ b/benchmarks/lexa/tree_explore/main.lx @@ -0,0 +1,95 @@ +effect Choice { + choose: () -> bool +} + +type list = + | Nil + | Cons of int * list + +type tree = + | Leaf + | Node of int * tree * tree + +def append(l1: list, l2: list): list { + match l1 with + | Nil -> { l2 } + | Cons (h, t) -> { + Cons (h, append(t, l2)) + } +} + +def list_max(l: list): int { + rec def list_max_rec <> (l: list, acc: int): int { + match l with + | Nil -> { acc } + | Cons (h, t) -> { + // ~printInt(h); + if h > acc then + list_max_rec(t, h) + else + list_max_rec(t, acc) + } + }; + list_max_rec(l, 0) +} + + +def operator(x: int, y: int): int { + ~mathAbs((x - 503 * y) + 37) % 1009 +} + +def make(n: int): tree { + if n == 0 then + Leaf + else + val t = make(n - 1); + Node(n, t, t) +} + +def explore [; choice_stub: Choice] (state: ref int, tre: tree): int { + match tre with + | Leaf -> { state[0] } + | Node (value, left, right) -> { + val next = + if raise choice_stub.choose() then + left + else + right + ; + state[0] := operator(state[0], value); + operator(value, explore:[; choice_stub](state, next)) + } +} + +def paths(state: ref int, tre: tree): list { + handle <> { + Cons (explore:[; choice_stub](state, tre), Nil) + } with choice_stub: Choice { + hdl_s choose(k) { + val arg1 = resume k true; + val arg2 = resume_final k false; + append(arg1, arg2) + } + } +} + +def loop(state: ref int, tre: tree, i: int): int { + if i == 0 then + state[0] + else + (state[0] := list_max(paths(state, tre)); + loop(state, tre, i - 1)) +} + +def run(n: int): int { + val tre = make(n); + val state = newref {0}; + loop(state, tre, 10) +} + +def main(): int { + val n = ~readInt(); + val res = run(n); + ~printInt(res); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/triples/main.lx b/benchmarks/lexa/triples/main.lx new file mode 100644 index 0000000..0957707 --- /dev/null +++ b/benchmarks/lexa/triples/main.lx @@ -0,0 +1,50 @@ +effect Choice { + flip: () -> int + fail: () -> int +} + +def choice [; choice_stub: Choice](n: int): int { + if n < 1 then + raise choice_stub.fail() + else + if raise choice_stub.flip() > 0 then + n + else + choice:[; choice_stub](n - 1) +} + +def triple [; choice_stub: Choice] (n: int, s: int): int { + val i = choice:[; choice_stub](n); + val j = choice:[; choice_stub](i - 1); + val k = choice:[; choice_stub](j - 1); + if i + j + k == s then + hash(i, j, k) + else + raise choice_stub.fail() +} + +def run(n: int, s: int): int { + handle <> { + triple:[; choice_stub](n, s) + } with choice_stub: Choice { + exc fail() { + 0 + } + + hdl_s flip(k) { + (resume k 1 + resume_final k 0) % 1000000007 + } + } +} + +def hash(a: int, b: int, c: int): int { + (53 * a + 2809 * b + 148877 * c) % 1000000007 +} + +def main(): int { + val n = ~readInt(); + val res = run(n, n); + ~printInt(res); + 0 +} + diff --git a/systems/lexa/Dockerfile b/systems/lexa/Dockerfile new file mode 100644 index 0000000..6d41fa0 --- /dev/null +++ b/systems/lexa/Dockerfile @@ -0,0 +1,19 @@ +FROM nixos/nix + +RUN mkdir lexa +WORKDIR /home/ubuntu/lexa + +RUN git clone --branch OOPSLA25 --depth 1 git@github.com:lexa-lang/lexa.git . + +RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#clang_18_preserve_none --cores 16 +RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link nixpkgs#texliveSmall --cores 16 +RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#effect_latest --cores 16 +RUN nix --extra-experimental-features "nix-command flakes" develop -j8 --cores 2 +RUN nix --extra-experimental-features "nix-command flakes" develop --command bash -c "opam init --disable-sandboxing && eval $(opam env) && opam switch create -y 5.3.0 && opam install -y multicont" +RUN nix-env -iA nixpkgs.util-linux nixpkgs.time + +RUN echo -e '#!/usr/bin/env bash\n\ +nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop' > /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file From 335e7cd46212dfd2ae020cb63363ff393f9e4b6b Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 13:41:30 -0400 Subject: [PATCH 02/11] Update Dockerfile --- systems/lexa/Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/systems/lexa/Dockerfile b/systems/lexa/Dockerfile index 6d41fa0..368b736 100644 --- a/systems/lexa/Dockerfile +++ b/systems/lexa/Dockerfile @@ -1,9 +1,10 @@ FROM nixos/nix -RUN mkdir lexa -WORKDIR /home/ubuntu/lexa +WORKDIR /WorkDir -RUN git clone --branch OOPSLA25 --depth 1 git@github.com:lexa-lang/lexa.git . +RUN curl -o lexa-oopsla25.tar.gz -sL https://github.com/lexa-lang/lexa/archive/refs/tags/OOPSLA25.tar.gz +RUN tar xvf lexa-oopsla25.tar.gz +WORKDIR ./lexa-OOPSLA25 RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#clang_18_preserve_none --cores 16 RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link nixpkgs#texliveSmall --cores 16 From c56d26cd93eeb92bd8955ef42ec768f317ac91b8 Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 13:53:36 -0400 Subject: [PATCH 03/11] clean up Dockerfile --- systems/lexa/Dockerfile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/systems/lexa/Dockerfile b/systems/lexa/Dockerfile index 368b736..38bcef2 100644 --- a/systems/lexa/Dockerfile +++ b/systems/lexa/Dockerfile @@ -6,11 +6,8 @@ RUN curl -o lexa-oopsla25.tar.gz -sL https://github.com/lexa-lang/lexa/archive/r RUN tar xvf lexa-oopsla25.tar.gz WORKDIR ./lexa-OOPSLA25 -RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#clang_18_preserve_none --cores 16 -RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link nixpkgs#texliveSmall --cores 16 -RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#effect_latest --cores 16 -RUN nix --extra-experimental-features "nix-command flakes" develop -j8 --cores 2 -RUN nix --extra-experimental-features "nix-command flakes" develop --command bash -c "opam init --disable-sandboxing && eval $(opam env) && opam switch create -y 5.3.0 && opam install -y multicont" +RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#clang_18_preserve_none +RUN nix --extra-experimental-features "nix-command flakes" develop RUN nix-env -iA nixpkgs.util-linux nixpkgs.time RUN echo -e '#!/usr/bin/env bash\n\ From 01b0b382617ccfca42f084982a38dceab9df7f65 Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 13:59:01 -0400 Subject: [PATCH 04/11] Update Benchmark availability --- README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 9023fbd..7800191 100644 --- a/README.md +++ b/README.md @@ -5,32 +5,32 @@ effect handlers, `benchmarks` implemented in those systems, and scripts to build the systems, run the benchmarks, and produce the results. A `system` may either be a programming language that has native support for -effect handlers, or a library that embeds effect handlers in another programming +effect handlers, or library that embeds effect handlers in another programmin language. ## Quick start -Ensure that [Docker](https://www.docker.com/) is installed on your system. Then, +Ensure that [Docker](https://www.docker.com/) is installe on your system. Then, ```bash $ make bench_ocaml -``` +`` -runs the OCaml benchmarks and produces `benchmarks/ocaml/results.csv` which -contains the results of running the OCaml benchmarks. +runs the OCaml benchmarks and produces `benchmarks/ocaml/results.csv` whic +contains the results of running the OCam benchmarks. ## System availability | System | Availability | -|--------|--------------| +|-------|--------------| | [Eff](https://github.com/matijapretnar/eff) | [![Eff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_eff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_eff.yml) | | [Effekt](https://github.com/effekt-lang/effekt) | [![Effekt](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_effekt.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_effekt.yml) | -| [Handlers in Action](https://github.com/slindley/effect-handlers) | [![Handlers in Action](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml) | +| [Handlers in Action](https://github.com/slindley/effect-handlers) | [![Handlers in Action](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml | | [Koka](https://github.com/koka-lang/koka) | [![Koka](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_koka.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_koka.yml) | | [Lexa](https://github.com/lexa-lang/lexa) | [![Lexa](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_lexa.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_lexa.yml) | | [libhandler](https://github.com/koka-lang/libhandler) | [![libhandler](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libhandler.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libhandler.yml) | | [libmpeff](https://github.com/koka-lang/libmprompt) | [![libmpeff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libmpeff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libmpeff.yml) | -| [libseff](https://github.com/effect-handlers/libseff.git) | [![libseff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml) | +| [libseff](https://github.com/effect-handlers/libseff.git | [![libseff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml) | | [Links](https://github.com/links-lang/links) | [![Links](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_links.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_links.yml) | | [OCaml](https://github.com/ocaml/ocaml)\* | [![OCaml](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_ocaml.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_ocaml.yml) | @@ -38,19 +38,19 @@ contains the results of running the OCaml benchmarks. ## Benchmark availability -| | Eff | Effekt | Handlers in Action | Koka | OCaml | Libseff | Libmpeff | -| :---------------------- | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | -| **Countdown** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Fibonacci Recursive** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Product Early** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Iterator** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Nqueens** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :x: | -| **Generator** | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Tree explore** | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :x: | -| **Triples** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :x: | -| **Parsing Dollars** | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Resume Nontail** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| **Handler Sieve** | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| | Eff | Effekt | Handlers in Action | Koka | OCaml | Lexa | Libseff | Libmpeff | +| :---------------------- | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | +| **Countdown** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Fibonacci Recursive** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Product Early** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Iterator** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Nqueens** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :x: | +| **Generator** | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Tree explore** | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :x: | +| **Triples** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :x: | +| **Parsing Dollars** | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Resume Nontail** | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| **Handler Sieve** | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Legend: From d5aa8334d4c8158a1776bfb2e4d19914719ed0a0 Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 14:11:13 -0400 Subject: [PATCH 05/11] Update Dockerfile --- systems/lexa/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/systems/lexa/Dockerfile b/systems/lexa/Dockerfile index 38bcef2..2524d42 100644 --- a/systems/lexa/Dockerfile +++ b/systems/lexa/Dockerfile @@ -6,8 +6,7 @@ RUN curl -o lexa-oopsla25.tar.gz -sL https://github.com/lexa-lang/lexa/archive/r RUN tar xvf lexa-oopsla25.tar.gz WORKDIR ./lexa-OOPSLA25 -RUN nix --extra-experimental-features "nix-command flakes" build --accept-flake-config --no-link .#clang_18_preserve_none -RUN nix --extra-experimental-features "nix-command flakes" develop +RUN nix --extra-experimental-features "nix-command flakes" develop --accept-flake-config RUN nix-env -iA nixpkgs.util-linux nixpkgs.time RUN echo -e '#!/usr/bin/env bash\n\ From 12921657f5c9df28afbc96120b2e370744f02385 Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 15:14:58 -0400 Subject: [PATCH 06/11] Update Dockerfile --- systems/lexa/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/systems/lexa/Dockerfile b/systems/lexa/Dockerfile index 2524d42..862a6eb 100644 --- a/systems/lexa/Dockerfile +++ b/systems/lexa/Dockerfile @@ -6,11 +6,10 @@ RUN curl -o lexa-oopsla25.tar.gz -sL https://github.com/lexa-lang/lexa/archive/r RUN tar xvf lexa-oopsla25.tar.gz WORKDIR ./lexa-OOPSLA25 -RUN nix --extra-experimental-features "nix-command flakes" develop --accept-flake-config -RUN nix-env -iA nixpkgs.util-linux nixpkgs.time +RUN nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop .#userShell RUN echo -e '#!/usr/bin/env bash\n\ -nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop' > /entrypoint.sh +nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop .#userShell' > /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file From 0230e3acc865a59dc6bb61e684c2f3ffa20c988c Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 15:21:45 -0400 Subject: [PATCH 07/11] fix typo --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7800191..ee42fab 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ effect handlers, `benchmarks` implemented in those systems, and scripts to build the systems, run the benchmarks, and produce the results. A `system` may either be a programming language that has native support for -effect handlers, or library that embeds effect handlers in another programmin +effect handlers, or a library that embeds effect handlers in another programming language. ## Quick start @@ -16,8 +16,8 @@ Ensure that [Docker](https://www.docker.com/) is installe on your system. Then, $ make bench_ocaml `` -runs the OCaml benchmarks and produces `benchmarks/ocaml/results.csv` whic -contains the results of running the OCam benchmarks. +runs the OCaml benchmarks and produces `benchmarks/ocaml/results.csv` which +contains the results of running the OCaml benchmarks. ## System availability From a83bd8d4d6cd617ad24d9658d4cd1c7ab2a1741a Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 15:24:36 -0400 Subject: [PATCH 08/11] fix typo --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ee42fab..b8e1ea3 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ language. ## Quick start -Ensure that [Docker](https://www.docker.com/) is installe on your system. Then, +Ensure that [Docker](https://www.docker.com/) is installed on your system. Then, ```bash $ make bench_ocaml -`` +``` runs the OCaml benchmarks and produces `benchmarks/ocaml/results.csv` which contains the results of running the OCaml benchmarks. @@ -25,12 +25,12 @@ contains the results of running the OCaml benchmarks. |-------|--------------| | [Eff](https://github.com/matijapretnar/eff) | [![Eff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_eff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_eff.yml) | | [Effekt](https://github.com/effekt-lang/effekt) | [![Effekt](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_effekt.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_effekt.yml) | -| [Handlers in Action](https://github.com/slindley/effect-handlers) | [![Handlers in Action](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml | +| [Handlers in Action](https://github.com/slindley/effect-handlers) | [![Handlers in Action](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_hia.yml) | | [Koka](https://github.com/koka-lang/koka) | [![Koka](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_koka.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_koka.yml) | | [Lexa](https://github.com/lexa-lang/lexa) | [![Lexa](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_lexa.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_lexa.yml) | | [libhandler](https://github.com/koka-lang/libhandler) | [![libhandler](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libhandler.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libhandler.yml) | | [libmpeff](https://github.com/koka-lang/libmprompt) | [![libmpeff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libmpeff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libmpeff.yml) | -| [libseff](https://github.com/effect-handlers/libseff.git | [![libseff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml) | +| [libseff](https://github.com/effect-handlers/libseff.git) | [![libseff](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_libseff.yml) | | [Links](https://github.com/links-lang/links) | [![Links](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_links.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_links.yml) | | [OCaml](https://github.com/ocaml/ocaml)\* | [![OCaml](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_ocaml.yml/badge.svg)](https://github.com/effect-handlers/effect-handlers-bench/actions/workflows/system_ocaml.yml) | From 388a1135d3cbede3e6a80ca80054f50b3f62d529 Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 16:45:51 -0400 Subject: [PATCH 09/11] Update Dockerfile --- systems/lexa/Dockerfile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/systems/lexa/Dockerfile b/systems/lexa/Dockerfile index 862a6eb..fcfa33e 100644 --- a/systems/lexa/Dockerfile +++ b/systems/lexa/Dockerfile @@ -9,7 +9,16 @@ WORKDIR ./lexa-OOPSLA25 RUN nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop .#userShell RUN echo -e '#!/usr/bin/env bash\n\ -nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop .#userShell' > /entrypoint.sh +set -e\n\ +\n\ +# Always run within the nix development environment\n\ +if [ $# -eq 0 ]; then\n\ + # If no arguments provided, start interactive shell\n\ + nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop .#userShell\n\ +else\n\ + # Run the command within the nix development environment\n\ + nix --extra-experimental-features "nix-command flakes" --accept-flake-config develop .#userShell --command "$@"\n\ +fi' > /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file From 53465ef439c6fd0cb6a47cab1cc7c3fcd73b1b1c Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 17:02:54 -0400 Subject: [PATCH 10/11] add missing benchmarks --- benchmarks/lexa/Makefile | 10 ++++- benchmarks/lexa/generator/main.lx | 58 +++++++++++++++++++++++++++ benchmarks/lexa/handler_sieve/main.lx | 39 ++++++++++++++++++ 3 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 benchmarks/lexa/generator/main.lx create mode 100644 benchmarks/lexa/handler_sieve/main.lx diff --git a/benchmarks/lexa/Makefile b/benchmarks/lexa/Makefile index dd82cda..6db3ee9 100644 --- a/benchmarks/lexa/Makefile +++ b/benchmarks/lexa/Makefile @@ -5,10 +5,12 @@ bench: build 'product_early/main 100000' \ 'iterator/main 40000000' \ 'nqueens/main 12' \ + 'generator/main 25' \ 'tree_explore/main 16' \ - 'triples/main 300' \ + 'triples/main 300 300' \ 'parsing_dollars/main 20000' \ - 'resume_nontail/main 20000' + 'resume_nontail/main 20000' \ + 'handler_sieve/main 60000' test: build cd countdown ; ./main 5 > actual ; echo 0 > expected ; diff expected actual @@ -16,10 +18,12 @@ test: build cd product_early ; ./main 5 > actual ; echo 0 > expected ; diff expected actual cd iterator ; ./main 5 > actual ; echo 15 > expected ; diff expected actual cd nqueens ; ./main 5 > actual ; echo 10 > expected ; diff expected actual + cd generator ; ./main 5 > actual ; echo 57 > expected ; diff expected actual cd tree_explore ; ./main 5 > actual ; echo 946 > expected ; diff expected actual cd triples ; ./main 10 > actual ; echo 779312 > expected ; diff expected actual cd parsing_dollars ; ./main 10 > actual ; echo 55 > expected ; diff expected actual cd resume_nontail ; ./main 5 > actual ; echo 37 > expected ; diff expected actual + cd handler_sieve ; ./main 10 > actual ; echo 17 > expected ; diff expected actual build: cd countdown ; lexa main.lx -o main @@ -27,10 +31,12 @@ build: cd product_early ; lexa main.lx -o main cd iterator ; lexa main.lx -o main cd nqueens ; lexa main.lx -o main + cd generator ; lexa main.lx -o main cd tree_explore ; lexa main.lx -o main cd triples ; lexa main.lx -o main cd parsing_dollars ; lexa main.lx -o main cd resume_nontail ; lexa main.lx -o main + cd handler_sieve ; lexa main.lx -o main clean: -rm */clue_table.txt diff --git a/benchmarks/lexa/generator/main.lx b/benchmarks/lexa/generator/main.lx new file mode 100644 index 0000000..fd6a978 --- /dev/null +++ b/benchmarks/lexa/generator/main.lx @@ -0,0 +1,58 @@ +effect Yield { + yield: (int) -> unit +} + +type tree = + | Leaf + | Node of int * tree * tree + +type generator = + | Empty + | Thunk of int * (cont <> unit -> generator) + +def make(n: int): tree { + if n == 0 then + Leaf + else + val t = make(n - 1); + Node(n, t, t) +} + +def iterate [; yield_stub: Yield] (t: tree): int { + match t with + | Leaf -> { 0 } + | Node (value, left, right) -> { + iterate: [; yield_stub] (left); + raise yield_stub.yield(value); + iterate: [; yield_stub] (right) + } +} + +def generate(f: <> [; yield_stub: Yield] () -> int): generator { + handle <> { + f:[; yield_stub](); + Empty() + } with yield_stub: Yield { + hdl_1 yield(x, k) { + Thunk(x, k) + } + } +} + +def sum(a: int, g: generator): int { + match g with + | Empty -> { a } + | Thunk (v, f) -> { + sum(v + a, resume_final f (())) + } +} + +def run(n: int): int { + val f = fun <> [; yield_stub: Yield] (): int { iterate:[; yield_stub](make(n)) }; + sum(0, generate(f)) +} + +def main(): int { + ~printInt(run(~readInt())); + 0 +} \ No newline at end of file diff --git a/benchmarks/lexa/handler_sieve/main.lx b/benchmarks/lexa/handler_sieve/main.lx new file mode 100644 index 0000000..ba8934c --- /dev/null +++ b/benchmarks/lexa/handler_sieve/main.lx @@ -0,0 +1,39 @@ +effect Prime { + prime: (int) -> bool +} + +def primes [; prime_stub: Prime] (i: int, n: int, a: int): int { + if i < n then + if raise prime_stub.prime(i) then + handle { + primes: [;new_prime_stub](i + 1, n, a + i) + } with new_prime_stub: Prime { + def prime(e) { + if (e % i) == 0 then + false + else + raise prime_stub.prime(e) + } + } + else + primes: [; prime_stub](i + 1, n, a) + else + a +} + +def run(n: int): int { + handle <> { + primes: [;prime_true_stub](2, n, 0) + } with prime_true_stub: Prime { + def prime(e) { + true + } + } +} + +def main(): int { + val arg1 = ~readInt(); + val arg2 = run(arg1); + ~printInt(arg2); + 0 +} \ No newline at end of file From b878d3da43757b8da40c05f611b6ecf5c0cd6eaa Mon Sep 17 00:00:00 2001 From: Cong Ma Date: Mon, 11 Aug 2025 17:06:31 -0400 Subject: [PATCH 11/11] triples take in one argument --- benchmarks/lexa/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/lexa/Makefile b/benchmarks/lexa/Makefile index 6db3ee9..8b07f1f 100644 --- a/benchmarks/lexa/Makefile +++ b/benchmarks/lexa/Makefile @@ -7,7 +7,7 @@ bench: build 'nqueens/main 12' \ 'generator/main 25' \ 'tree_explore/main 16' \ - 'triples/main 300 300' \ + 'triples/main 300' \ 'parsing_dollars/main 20000' \ 'resume_nontail/main 20000' \ 'handler_sieve/main 60000'