on master help sign in
Add Clojure support (#30)
commit170c83deca2e3eb917506b881340a234b6abc53a authorSalam Elbilig <finalfantasia@users.noreply.github.com> dateMon 4 Nov 2019, 15:40 (7 years ago) parent84ced5d
16 files changed+288−1
README.md+1 languages/clojure/main.go+103 languages/clojure/prybar_repl.clj+11 scripts/docker-install.sh+10 scripts/gofiles.sh+1−1 test_files/hello.clj+3 tests/clojure/all.exp+39 tests/clojure/evaluate_expression.exp+11 tests/clojure/initialize_code_with_script.exp+11 tests/clojure/initialize_expression_with_script.exp+10 tests/clojure/initialize_repl_with_script.exp+21 tests/clojure/plus_1_1.exp+19 tests/clojure/print.exp+24 tests/clojure/quiet_repl.exp+11 tests/clojure/run_code.exp+8 tests/clojure/run_script.exp+5
README.md+1
@@ -36,6 +36,7 @@ written in the host language which starts a Prybar-compatible REPL.
3636
3737| language | eval | eval expression | eval file | repl | repl like eval | set prompt |
3838| ------------------------- | ---- | --------------- | --------- | ---- | -------------- | ---------- |
39+| Clojure | ✔ | ✔ | ✔ | ✔ | ✔ | - |
3940| Emacs Lisp | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ |
4041| Javascript (nodejs) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
4142| Javascript (spidermonkey) | ✔ | ✗ | ✗ | ✗ | ✗ | - |
languages/clojure/main.gonew file+103
@@ -0,0 +1,103 @@
1+package main
2+
3+//go:generate ../../scripts/gofiles.sh generated_files.go
4+
5+import (
6+ "fmt"
7+ "io/ioutil"
8+ "os"
9+ "os/exec"
10+ "syscall"
11+ "github.com/replit/prybar/utils"
12+)
13+
14+func findHelper(path string) string {
15+ fileName := path + ".clj"
16+ bytes, err := File(fileName)
17+ if bytes != nil {
18+ f, err := ioutil.TempFile("", fileName)
19+ if err != nil {
20+ panic(err)
21+ }
22+
23+ if _, err = f.Write(bytes); err != nil {
24+ panic(err)
25+ }
26+ if err = f.Close(); err != nil {
27+ panic(err)
28+ }
29+ return f.Name()
30+ }
31+ if err != nil {
32+ panic(err)
33+ }
34+ panic("File not found: " + fileName)
35+}
36+
37+func Execute(config *utils.Config) {
38+ path, err := exec.LookPath("clj")
39+
40+ if err != nil {
41+ panic(err)
42+ }
43+
44+ env := os.Environ()
45+ args := []string{"clj"}
46+
47+ hasOption := config.Code != "" || config.Exp != "" ||
48+ config.Interactive || config.OurInteractive
49+ hasFile := false
50+
51+ if config.Ps1 != "" {
52+ args = append(args, "-J-DPRYBAR_PS1=" + config.Ps1)
53+ }
54+
55+ if config.Ps2 != "" {
56+ args = append(args, "-J-DPRYBAR_PS2=" + config.Ps2)
57+ }
58+
59+ if config.Quiet {
60+ args = append(args, "-J-DPRYBAR_QUIET=true")
61+ }
62+
63+ if hasOption {
64+ if config.Args != nil && len(config.Args) > 0 {
65+ if _, err := os.Stat(config.Args[0]); os.IsNotExist(err) {
66+ fmt.Println("No such file:", config.Args[0])
67+ os.Exit(2)
68+ }
69+
70+ hasFile = true
71+ }
72+
73+ if hasFile {
74+ args = append(args, "--init", config.Args[0])
75+ }
76+
77+ if config.Code != "" {
78+ // "--eval" prints non-nil results only.
79+ effect := fmt.Sprintf("(do %s nil)", config.Code)
80+ args = append(args, "--eval", effect)
81+ }
82+
83+ if config.Exp != "" {
84+ args = append(args, "--eval", config.Exp)
85+ }
86+
87+ if config.Interactive || config.OurInteractive {
88+ args = append(args, findHelper("prybar_repl"))
89+ }
90+
91+ if hasFile {
92+ args = append(args, config.Args[1:]...)
93+ } else {
94+ args = append(args, config.Args...)
95+ }
96+ } else {
97+ args = append(args, "--eval", "")
98+ args = append(args, config.Args...)
99+ }
100+
101+ syscall.Exec(path, args, env)
102+}
103+
languages/clojure/prybar_repl.cljnew file+11
@@ -0,0 +1,11 @@
1+(def prybar-ps1 (System/getProperty "PRYBAR_PS1" "--> "))
2+(def prybar-quiet? (System/getProperty "PRYBAR_QUIET" "false"))
3+
4+(when-not (Boolean/valueOf prybar-quiet?)
5+ (println "Clojure" (clojure-version)))
6+
7+(clojure.main/repl :init #(apply require clojure.main/repl-requires)
8+ :prompt #(print prybar-ps1))
9+(prn)
10+(System/exit 0)
11+
scripts/docker-install.sh+10
@@ -8,6 +8,7 @@ cd /tmp
88packages="
99
1010# languages
11+default-jre-headless
1112emacs-nox
1213liblua5.1-dev
1314nodejs
@@ -33,8 +34,12 @@ libnspr4-dev
3334
3435# used during installation
3536git
37+curl
3638wget
3739
40+# used during runtime
41+rlwrap
42+
3843"
3944
4045export DEBIAN_FRONTEND=noninteractive
@@ -42,6 +47,11 @@ apt-get update
4247apt-get install -y $(grep -v "^#" <<< "$packages")
4348rm -rf /var/lib/apt/lists/*
4449
50+clojure_version=1.10.1.478
51+wget "https://download.clojure.org/install/linux-install-${clojure_version}.sh"
52+chmod +x "linux-install-${clojure_version}.sh"
53+"./linux-install-${clojure_version}.sh"
54+
4555# The version in the Disco repos is out of date (1.0 series) and does
4656# not expose the API we need.
4757wget -nv https://julialang-s3.julialang.org/bin/linux/x64/1.1/julia-1.1.1-linux-x86_64.tar.gz
scripts/gofiles.sh+1−1
@@ -13,7 +13,7 @@ func File(name string) ([]byte, error) {
1313
1414EOF
1515
16−for fn in $(ls | egrep -i '.*\.(js|ml)'); do
16+for fn in $(ls | egrep -i '.*\.(clj|js|ml)'); do
1717
1818 echo " case \"$fn\":" >> $1
1919 echo " return base64.StdEncoding.DecodeString(\"$(base64 -i $fn | tr -d \\n)\")" >> $1
test_files/hello.cljnew file+3
@@ -0,0 +1,3 @@
1+(def a "hello")
2+(def b 42)
3+(println a)
tests/clojure/all.expnew file+39
@@ -0,0 +1,39 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -c {(defn f [x] (inc x))} -e {(def s "bar")} -I -i -q ./test_files/hello.clj
8+match_max 100000
9+expect -re "^${_}hello${_}\r
10+${_}#'user/s${_}\r
11+${_}--> $"
12+
13+# a is defined in ./test_files/hello.clj
14+send -- "a\r"
15+expect -re "^${_}a${_}\r
16+${_}\"hello\"${_}\r
17+${_}--> $"
18+
19+# b is defined in ./test_files/hello.clj
20+send -- "b\r"
21+expect -re "^${_}b${_}\r
22+${_}42${_}\r
23+${_}--> $"
24+
25+# defined with "-c"
26+send -- "(f b)\r"
27+expect -re "^${_}(f b)${_}\r
28+${_}43${_}\r
29+${_}--> $"
30+
31+# defined with "-e"
32+send -- "s\r"
33+expect -re "^${_}s${_}\r
34+${_}\"bar\"${_}\r
35+${_}--> $"
36+
37+send -- ""
38+expect eof
39+
tests/clojure/evaluate_expression.expnew file+11
@@ -0,0 +1,11 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -e {(str (+ 1 1))}
8+match_max 100000
9+expect -re "^${_}\"2\"${_}$"
10+expect eof
11+
tests/clojure/initialize_code_with_script.expnew file+11
@@ -0,0 +1,11 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -c {(do (print (str a " " b)) "return-value")} ./test_files/hello.clj
8+match_max 100000
9+expect -re "^${_}hello 42${_}$"
10+expect eof
11+
tests/clojure/initialize_expression_with_script.expnew file+10
@@ -0,0 +1,10 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -e "(str (inc b))" ./test_files/hello.clj
8+match_max 100000
9+expect -re "^${_}\"43\"${_}\r$"
10+
tests/clojure/initialize_repl_with_script.expnew file+21
@@ -0,0 +1,21 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -i ./test_files/hello.clj
8+match_max 100000
9+expect -re "^${_}hello${_}\r
10+${_}Clojure${_}\r
11+${_}--> $"
12+
13+# b is defined in ./test_files/hello.clj
14+send -- "b\r"
15+expect -re "^${_}b${_}\r
16+${_}42${_}\r
17+${_}--> $"
18+
19+send -- ""
20+expect eof
21+
tests/clojure/plus_1_1.expnew file+19
@@ -0,0 +1,19 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -i
8+match_max 100000
9+expect -re "^${_}Clojure${_}\r
10+${_}--> $"
11+
12+send -- "(str (+ 1 1))\r"
13+expect -re "${_}\\(str \\(\\+ 1 1\\)\\)${_}\r
14+${_}2${_}\r
15+${_}--> $"
16+
17+send -- ""
18+expect eof
19+
tests/clojure/print.expnew file+24
@@ -0,0 +1,24 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+set timeout -1
7+spawn ./prybar-clojure -i
8+match_max 100000
9+expect -re "^${_}Clojure${_}\r
10+${_}--> $"
11+
12+send -- "(print \"hello!\")\r"
13+expect -re "^${_}\\(print \"hello!\"\\)${_}\r
14+${_}hello!nil${_}\r
15+${_}--> $"
16+
17+send -- "(print (+ 1 1))\r"
18+expect -re "^${_}\\(print \\(\\+ 1 1\\)\\)${_}\r
19+${_}2nil${_}\r
20+${_}--> $"
21+
22+send -- ""
23+expect eof
24+
tests/clojure/quiet_repl.expnew file+11
@@ -0,0 +1,11 @@
1+#!/usr/bin/expect -f
2+
3+# ignore ANSI escape sequences
4+set _ "(?:.*?)"
5+
6+spawn ./prybar-clojure -i -q
7+expect -re "^${_}--> $"
8+
9+send -- ""
10+expect eof
11+
tests/clojure/run_code.expnew file+8
@@ -0,0 +1,8 @@
1+#!/usr/bin/expect -f
2+
3+set timeout -1
4+spawn ./prybar-clojure -c {(do (println "foo") "bar")}
5+match_max 100000
6+expect -re "^\r\r\u001b\\\[K\rfoo\r\r\n$"
7+expect eof
8+
tests/clojure/run_script.expnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/expect -f
2+
3+spawn ./prybar-clojure ./test_files/hello.clj
4+expect eof
5+