OILS / test / shell-vs-shell.sh View on Github | oilshell.org

314 lines, 142 significant
1#!/usr/bin/env bash
2#
3# Compare alternative shell designs!
4#
5# Usage:
6# test/shell-vs-shell.sh <function name>
7
8set -o nounset
9set -o pipefail
10set -o errexit
11
12readonly BASE_DIR=_tmp/shell-vs-shell
13readonly REPO_ROOT=$(cd $(dirname $0)/.. ; pwd)
14
15readonly TAB=$'\t'
16
17html-head() {
18 PYTHONPATH=. doctools/html_head.py "$@"
19}
20
21cmark() {
22 # copied from build/doc.sh
23 PYTHONPATH=. doctools/cmark.py --toc-tag h2 --toc-tag h3 --toc-pretty-href "$@"
24}
25
26highlight-code() {
27 PYTHONPATH=. doctools/oils_doc.py highlight "$@"
28}
29
30desc() {
31 echo "$@" > description.txt
32}
33
34src() {
35 local lang=$1
36
37 local prog=src/$lang
38
39 # read from stdin
40 cat > $prog
41
42 case $lang in
43 (oil)
44 $REPO_ROOT/bin/oil $prog | tee output/$lang.txt
45 ;;
46 (shpp)
47 ~/git/languages/shell-plus-plus/build/shell/shpp $prog | tee output/$lang.txt
48 ;;
49 (*)
50 die "Invalid language $lang"
51 ;;
52 esac
53}
54
55CASE-hello() {
56
57 desc "Print a string"
58
59 # TODO:
60 # - need to group these into a row somehow ...
61 # code-begin or something
62 # - setup script
63 # - show output in the HTML too
64 # - save that in a dir and then escape it
65
66 src oil <<'EOF'
67# oil requires quotes
68echo 'hello world'
69
70const name = 'world'
71echo "hello $name"
72EOF
73
74 src shpp <<'EOF'
75# no single quotes
76echo hello world
77
78name = "world"
79echo "hello ${name}" # braces required
80EOF
81}
82
83CASE-pipeline() {
84 desc 'Pipeline and Glob'
85
86 touch src{1,2,3,4,5}
87
88 src oil <<EOF
89ls src* | sort -r | head -n 3
90EOF
91
92 src shpp <<EOF
93ls src* | sort -r | head -n 3
94EOF
95
96}
97
98CASE-try() {
99 desc 'Error Handling'
100
101 src oil <<'EOF'
102# TODO: Oil could expose strerror() like shpp
103
104try zzz
105if (_status === 127) {
106 echo "zzz not installed"
107}
108EOF
109
110 src shpp <<'EOF'
111try {
112 zzz
113} catch InvalidCmdException as ex {
114 print("zzz not installed [msg: ", ex, "]")
115}
116EOF
117}
118
119CASE-read() {
120 desc 'Read User Input'
121
122 src oil <<'EOF'
123echo hello | read --line
124
125# _line starts with _, so it's a
126# "register" mutated by the interpreter
127echo "line: $_line"
128EOF
129
130 src shpp <<'EOF'
131# not sure how to feed stdin
132
133line = read()
134print("line: ", line)
135EOF
136}
137
138# TODO: Sort by section
139CASE-ZZ-array() {
140 desc 'Use Arrays'
141
142 touch {foo,bar}.py
143
144 src oil <<'EOF'
145const array1 = ['physics', 'chemistry', 1997, 2000]
146const array2 = [1, 2, 3, 4, 5, 6, 7]
147
148write -- "array1[0]: $[array1[0]]"
149
150# TODO: Oil needs @[]
151const slice = array2[1:5]
152write -- "array2[1:5]" @slice
153
154# use the word language: bare words, glob, brace expansion
155const shell_style = %( README.md *.py {alice,bob}@example.com )
156write -- @shell_style
157EOF
158
159 src shpp <<'EOF'
160array1 = ["physics", "chemistry", 1997, 2000];
161array2 = [1, 2, 3, 4, 5, 6, 7 ];
162
163print("array1[0]: ", array1[0])
164print("array2[1:5]: ", array2[1:5])
165EOF
166
167}
168
169CASE-path() {
170 desc 'Test if path exists'
171
172 src oil <<'EOF'
173if test --exists /bin/grep {
174 echo 'file exists'
175}
176EOF
177
178 src shpp <<'EOF'
179if path("/bin/grep").exists() {
180 echo "file exists"
181}
182EOF
183}
184
185test-one() {
186 local func_name=$1
187
188 echo "$TAB---"
189 echo "$TAB$func_name"
190 echo "$TAB---"
191
192 local dir=$BASE_DIR/$func_name
193
194 mkdir -p $dir/{src,output}
195 pushd $dir >/dev/null
196
197 $func_name
198
199 popd >/dev/null
200
201}
202
203test-all() {
204 rm -r -f -v $BASE_DIR/
205 mkdir -p $BASE_DIR/
206 compgen -A function | grep '^CASE-' | xargs -n 1 -- $0 test-one
207
208 tree $BASE_DIR
209}
210
211html-escape() {
212 sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' "$@"
213}
214
215html-footer() {
216 echo '
217 </body>
218</html>
219'
220}
221
222# TODO: Run through doctools plugin for syntax highlighting
223
224make-table() {
225 echo '<h2>'
226 html-escape description.txt
227 echo '</h2>'
228
229 echo '<table>'
230 echo ' <thead>'
231 echo ' <tr>'
232 echo ' <td></td>'
233 for src_file in src/*; do
234 echo "<td>$(basename $src_file)</td>"
235 done
236 echo ' </tr>'
237 echo ' </thead>'
238
239 echo ' <tr>'
240 echo ' <td>source</td>'
241 for src_file in src/*; do
242 echo '<td><pre>'
243 cat $src_file | html-escape
244 echo '</pre></td>'
245 done
246 echo ' </tr>'
247
248 echo ' <tr>'
249 echo ' <td>output</td>'
250 for out_file in output/*; do
251 echo '<td><pre>'
252 cat $out_file | html-escape
253 echo '</pre></td>'
254 done
255 echo ' </tr>'
256
257 echo '</table>'
258}
259
260
261_html-all() {
262 html-head --title 'Shell vs. Shell' \
263 ../web/base.css ../web/shell-vs-shell.css ../web/language.css
264
265 echo '<body class="width50">'
266
267 cmark <<EOF
268# Shell Design Comparison
269
270This is a friendly comparison of the syntax of different shells!
271
272- Oil: <https://github.com/oilshell/oil>
273 - [A Tour of the Oil
274 Language](https://www.oilshell.org/release/latest/doc/oil-language-tour.html)
275- Shell++: <https://github.com/alexst07/shell-plus-plus>
276 - [Shell++ Language Basics](https://alexst07.github.io/shell-plus-plus/lang-basics/)
277
278&nbsp;
279
280- More shells: <https://github.com/oilshell/oil/wiki/Alternative-Shells>
281- Script that generates this file:
282 <https://github.com/oilshell/oil/blob/master/test/shell-vs-shell.sh>
283
284&nbsp;
285
286EOF
287
288 for dir in $BASE_DIR/CASE-*; do
289 pushd $dir >/dev/null
290
291 make-table
292
293 popd >/dev/null
294 done
295
296 html-footer
297}
298
299html-all() {
300 mkdir -p $BASE_DIR
301
302 local out=$BASE_DIR/index.html
303
304 _html-all | highlight-code > $out
305
306 echo "Wrote $out"
307}
308
309all() {
310 test-all
311 html-all
312}
313
314"$@"