| 1 | #!/usr/bin/env bash
 | 
| 2 | #
 | 
| 3 | # Usage:
 | 
| 4 | #   demo/matchertext.sh <function name>
 | 
| 5 | 
 | 
| 6 | set -o nounset
 | 
| 7 | set -o pipefail
 | 
| 8 | set -o errexit
 | 
| 9 | 
 | 
| 10 | m-extensible() {
 | 
| 11 |   local lang=$1
 | 
| 12 |   shift
 | 
| 13 |   if "$@"; then
 | 
| 14 |     echo
 | 
| 15 |     echo "[$lang] NO, expected syntax error"
 | 
| 16 |   else
 | 
| 17 |     echo
 | 
| 18 |     echo "[$lang] YES"
 | 
| 19 |   fi
 | 
| 20 | 
 | 
| 21 |   echo
 | 
| 22 |   echo ---
 | 
| 23 |   echo
 | 
| 24 | }
 | 
| 25 | 
 | 
| 26 | # Other languages to test:
 | 
| 27 | #
 | 
| 28 | # - CSV -- seems unlikely that there is any syntactic room
 | 
| 29 | # - YAML -- maybe in its JSON subset, however most people seem to use the
 | 
| 30 | #   indented strings with a whitespace rule
 | 
| 31 | # - HTML and XML - addressed as '*ML' in the paper
 | 
| 32 | 
 | 
| 33 | demo() {
 | 
| 34 |   echo 'Are the string literals in this language M-extensible?'
 | 
| 35 |   echo 'We simply test them for syntax errors after a special char like \'
 | 
| 36 |   echo
 | 
| 37 |   echo 'This is also relevant to YSTR, where we add \xff and \u{012345} escapes'
 | 
| 38 |   echo
 | 
| 39 | 
 | 
| 40 |   mkdir -p _tmp
 | 
| 41 | 
 | 
| 42 |   local tmp=_tmp/foo.c
 | 
| 43 | 
 | 
| 44 |   cat >$tmp <<'EOF'
 | 
| 45 | import json
 | 
| 46 | json.loads('"\[]"')
 | 
| 47 | json.loads('"\m[]"')
 | 
| 48 | EOF
 | 
| 49 |   m-extensible 'JSON' python3 $tmp
 | 
| 50 | 
 | 
| 51 | 
 | 
| 52 |   # The only metacharacter in Ninja is $, and a literal dollar is $$ (similar
 | 
| 53 |   # to GNU make)
 | 
| 54 |   #
 | 
| 55 |   # You could imagine a matchertext literal as $[ cp $SHELL_VAR_NOT_NINJA_VAR x ]
 | 
| 56 |   #
 | 
| 57 |   # Ninja and GNU make's conflict with shell annoys me
 | 
| 58 | 
 | 
| 59 |   echo foo > _tmp/ninja-in
 | 
| 60 | 
 | 
| 61 |   cat >_tmp/z.ninja <<'EOF'
 | 
| 62 | rule copy
 | 
| 63 |   command = cp $in $out
 | 
| 64 | 
 | 
| 65 | build _tmp/out : copy _tmp/ninja-in
 | 
| 66 | 
 | 
| 67 | build _tmp/$[ : copy _tmp/ninja-in
 | 
| 68 | 
 | 
| 69 | EOF
 | 
| 70 |   m-extensible 'Ninja' ninja -f _tmp/z.ninja
 | 
| 71 | 
 | 
| 72 | 
 | 
| 73 |   echo foo > _tmp/make-in
 | 
| 74 | 
 | 
| 75 |   cat >_tmp/z.mk <<'EOF'
 | 
| 76 | _tmp/make-out : _tmp/make-in
 | 
| 77 | 	cp $< $@
 | 
| 78 | 
 | 
| 79 | _tmp/make-out : _tmp/make-in
 | 
| 80 | 	cp $[ $< $@
 | 
| 81 | EOF
 | 
| 82 |   m-extensible 'GNU Make' make -f _tmp/z.mk
 | 
| 83 | 
 | 
| 84 |   cat >$tmp <<'EOF'
 | 
| 85 | #include <stdio.h>
 | 
| 86 | int main() {
 | 
| 87 |   printf("\[]\n");
 | 
| 88 |   printf("\m[]\n");
 | 
| 89 | }
 | 
| 90 | EOF
 | 
| 91 |   m-extensible 'C' gcc -o /tmp/m $tmp
 | 
| 92 | 
 | 
| 93 |   echo 'Running C'
 | 
| 94 | 
 | 
| 95 |   # See what the output looks like
 | 
| 96 |   chmod +x /tmp/m
 | 
| 97 |   /tmp/m
 | 
| 98 | 
 | 
| 99 |   echo
 | 
| 100 |   echo ---
 | 
| 101 | 
 | 
| 102 |   m-extensible 'Python' python3 -c '
 | 
| 103 | print("\[]")
 | 
| 104 | print("\m[]")
 | 
| 105 | '
 | 
| 106 | 
 | 
| 107 |   m-extensible 'Shell' sh -c '
 | 
| 108 | echo "\[]"
 | 
| 109 | echo "\m[]"
 | 
| 110 | '
 | 
| 111 | 
 | 
| 112 |   # awk has warnings
 | 
| 113 |   echo input | m-extensible 'Awk' awk '
 | 
| 114 | {
 | 
| 115 |   print("\[]");
 | 
| 116 |   print("\m[]");
 | 
| 117 | }
 | 
| 118 | '
 | 
| 119 | 
 | 
| 120 |   m-extensible 'JavaScript' nodejs -e '
 | 
| 121 | console.log("\[]");
 | 
| 122 | console.log("\m[]");
 | 
| 123 | '
 | 
| 124 | }
 | 
| 125 | 
 | 
| 126 | "$@"
 |