Skip to content

Commit fd8cca9

Browse files
Add support for the Emacs Lisp programming language
1 parent 3025a53 commit fd8cca9

6 files changed

Lines changed: 108 additions & 2 deletions

File tree

dataset_builder/humaneval_to_el.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""
2+
This script translates problems from the OpenAI HumanEval dataset into Emacs Lisp.
3+
4+
- Home: https://www.gnu.org/software/emacs/
5+
- Reference manual: https://www.gnu.org/software/emacs/manual/elisp.html
6+
- Test library: https://www.gnu.org/software/emacs/manual/ert.html
7+
"""
8+
9+
import ast
10+
from typing import List
11+
12+
13+
class Translator:
14+
15+
USub = "-"
16+
17+
stop = ["\n(defun", "\n;", "\n("]
18+
19+
def file_ext(self):
20+
return "el"
21+
22+
def translate_prompt(
23+
self, name: str, args: List[ast.arg], _returns, description: str
24+
) -> str:
25+
self.entry_point = name
26+
el_preamble = ";;; -*- lexical-binding: t; -*-"
27+
el_args = " ".join(arg.arg for arg in args)
28+
el_description = description.replace('"', '\\"')
29+
return f'{el_preamble}\n(defun {name} ({el_args})\n "{el_description}"\n '
30+
31+
def test_suite_prefix_lines(self, entry_point) -> List[str]:
32+
return [
33+
f"(defalias #'candidate #'{entry_point})",
34+
"(ert-deftest test-human-eval ()",
35+
]
36+
37+
def test_suite_suffix_lines(self) -> List[str]:
38+
return [")"]
39+
40+
def deep_equality(self, left: str, right: str) -> str:
41+
return f" (should (equal {left} {right}))"
42+
43+
def gen_literal(self, c: bool | str | int | float):
44+
if type(c) is bool:
45+
return "t" if c else "nil"
46+
elif type(c) is str:
47+
return f'"{c}"'
48+
elif c is None:
49+
return "nil"
50+
return repr(c)
51+
52+
def gen_var(self, variable: str) -> str:
53+
return variable
54+
55+
def gen_list(self, list: List[str]) -> str:
56+
return "(list " + " ".join(list) + ")"
57+
58+
def gen_tuple(self, tuple: List[str]) -> str:
59+
return "(list " + " ".join(tuple) + ")"
60+
61+
def gen_dict(self, keys: List[str], values: List[str]) -> str:
62+
pairs = " ".join(f"(cons {k} {v})" for k, v in zip(keys, values))
63+
return "(list " + pairs + ")"
64+
65+
def gen_call(self, func: str, args: List[str]) -> str:
66+
return "(" + func + " " + " ".join(args) + ")"

dataset_builder/libexperiments.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@ def path(self) -> Path:
4242
"elixir",
4343
"clj",
4444
"ada",
45+
"el",
4546
]
4647
MODELS = ["davinci", "incoder", "codegen"]
4748

4849
def all_experiments() -> Iterator[Experiment]:
4950
"""
5051
An iterator that produces (lang, model, temp, variation) tuples for all
51-
the standard experiments that we care about. The ../experiments directory
52-
has results from configurations that were explored and determined
52+
the standard experiments that we care about. The ../experiments directory
53+
has results from configurations that were explored and determined
5354
uninteresting for a full result. (We are not deleting results.)
5455
"""
5556
for dataset in DATASETS:

dataset_builder/terms.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ Matlab,m,array,array,array,dictionary,<missing>,true,false
2626
Haskell,hs,list,list,tuple,association list,Nothing,True,False
2727
Clojure,clj,vector,list,vector,map,nil,true,false
2828
Dart,dart,list,list,record,map,null,true,false
29+
Emacs Lisp,el,list,list,list,alist,nil,t,nil

evaluation/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ RUN apt-get update -yqq && apt-get install -yqq dart
106106
# Lean
107107
# RUN wget https://github.com/leanprover/lean4/releases/download/v4.6.0-rc1/lean-4.6.0-rc1-linux.zip -O /tmp/lean.zip && unzip /tmp/lean.zip -d /root/lean/ && ln -s /root/lean/bin/lean /bin/lean
108108

109+
# Emacs Lisp (no-X/GUI version)
110+
RUN apt install -y emacs-nox
111+
109112
# install numpy for humanevalplus
110113
RUN python3 -m pip install numpy
111114

evaluation/src/containerized_eval.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import eval_v
3030
import eval_lean
3131
import eval_dart
32+
import eval_el
3233
import tempfile
3334

3435

@@ -65,6 +66,7 @@
6566
"coq": (eval_v.eval_script, ".v"),
6667
"lean": (eval_lean.eval_script, ".lean"),
6768
"dart": (eval_dart.eval_script, ".dart"),
69+
"el": (eval_el.eval_script, ".el"),
6870
}
6971

7072
def eval_string_script(language, program):

evaluation/src/eval_el.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Evaluates a generated Emacs Lisp program (.el).
3+
"""
4+
from pathlib import Path
5+
from safe_subprocess import run
6+
7+
def eval_script(path: Path):
8+
9+
result = run([
10+
"emacs", "-batch",
11+
"-l", "ert",
12+
"-l", str(path),
13+
"-f", "ert-run-tests-batch-and-exit"
14+
])
15+
16+
if result.timeout:
17+
status = "Timeout"
18+
elif result.exit_code != 0:
19+
status = "Exception"
20+
elif "\nRan 1 tests, 1 results as expected, 0 unexpected" in result.stderr:
21+
status = "OK"
22+
else: # test failure
23+
status = "Exception"
24+
25+
return {
26+
"status": status,
27+
"exit_code": result.exit_code,
28+
"stdout": result.stdout,
29+
"stderr": result.stderr,
30+
}
31+
32+
if __name__ == "__main__":
33+
main()

0 commit comments

Comments
 (0)