From 02028e90a422924a2eb96c735dd6809d2dd9e5a1 Mon Sep 17 00:00:00 2001 From: Andy Chu Date: Sat, 13 Jun 2020 10:57:13 -0700 Subject: [PATCH] impls/bash: Minor changes to make it run under OSH OSH is a bash-compatible shell: https://www.oilshell.org/ reader.sh: - Put the constant regex pattern in a string literal. This simplifies it by removing mixed regex vs. shell quoting, and implicit concatenation with $'\n'. This is suggested by the bash manual: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs "Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell." - Initialize __reader_tokens as an array, not a string. https://www.oilshell.org/release/0.8.pre6/doc/known-differences.html#values-are-tagged-with-types-not-cells env.sh: Simplify quoting in 'eval' expressions. This quotes associative array keys, which is required by OSH to avoid dynamic parsing. https://www.oilshell.org/release/0.8.pre6/doc/known-differences.html#strings-vs-bare-words-in-array-indices http://www.oilshell.org/blog/2016/10/20.html core.sh: Quote associative array keys. '<' and '>' are shell operators and OSH doesn't have a special case when inside []. ---- With this change, OSH can run tests just like bash, e.g.: $ osh impls/bash/stepA_mal.sh tests/step4_if_fn_do.mal ---- Test results are the same before and after this change: $ NO_DOCKER=1 ./.travis_test.sh test bash FAILURES: SOFT FAILED TEST (line 295): (f (+ 1 1)) -> ['',true]: Expected : '.*\ntrue' Got : '(f (+ 1 1))\nfalse' TEST RESULTS (for ../tests/stepA_mal.mal): 1: soft failing tests 0: failing tests 106: passing tests 107: total tests --- impls/bash/core.sh | 8 ++++---- impls/bash/env.sh | 4 ++-- impls/bash/reader.sh | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/impls/bash/core.sh b/impls/bash/core.sh index 154592ff..4994d0f3 100644 --- a/impls/bash/core.sh +++ b/impls/bash/core.sh @@ -376,10 +376,10 @@ declare -A core_ns=( [readline]=readline [read-string]=read_string [slurp]=slurp - [<]=num_lt - [<=]=num_lte - [>]=num_gt - [>=]=num_gte + ['<']=num_lt + ['<=']=num_lte + ['>']=num_gt + ['>=']=num_gte [+]=num_plus [-]=num_minus [__STAR__]=num_multiply diff --git a/impls/bash/env.sh b/impls/bash/env.sh index 9595aa25..d7646909 100644 --- a/impls/bash/env.sh +++ b/impls/bash/env.sh @@ -48,7 +48,7 @@ ENV_FIND () { r="${1}" else local obj="${ANON["${1}"]}" - eval local outer="\${${obj}["__outer__"]}" + eval 'local outer=${'${obj}'["__outer__"]}' if [[ "${outer}" && "${outer}" != "${__nil}" ]]; then ENV_FIND "${outer}" "${2}" else @@ -66,7 +66,7 @@ ENV_GET () { local key="${ANON["${2}"]}" if [[ "${r}" ]]; then local obj="${ANON["${env}"]}" - eval r="\${${obj}["${key}"]}" + eval 'r=${'${obj}'["'${key}'"]}' else _error "'${key}' not found" fi diff --git a/impls/bash/reader.sh b/impls/bash/reader.sh index f1d53d09..6e1ed362 100644 --- a/impls/bash/reader.sh +++ b/impls/bash/reader.sh @@ -103,6 +103,8 @@ READ_FORM () { esac } +TOKEN_PAT=$'^^([][{}\\(\\)^@])|^(~@)|^("(\\\\.|[^\\"])*"?)|^(;[^\n]*)|^([~\'`])|^([^][ ~`\'";{}\\(\\)^@,\n]+)|^(,)|^([[:space:]]+)' + # Returns __reader_tokens as an indexed array of tokens TOKENIZE () { local data="${*}" @@ -114,14 +116,14 @@ TOKENIZE () { local str= __reader_idx=0 - __reader_tokens= + declare -a -g __reader_tokens=() # global array while true; do if (( ${#str} < ( chunksz / 2) )) && (( chunk < datalen )); then str="${str}${data:${chunk}:${chunksz}}" chunk=$(( chunk + ${chunksz} )) fi (( ${#str} == 0 )) && break - [[ "${str}" =~ ^^([][{}\(\)^@])|^(~@)|^(\"(\\.|[^\\\"])*\"?)|^(;[^$'\n']*)|^([~\'\`])|^([^][ ~\`\'\";{}\(\)^@\,$'\n']+)|^(,)|^([[:space:]]+) ]] + [[ "${str}" =~ ${TOKEN_PAT} ]] token=${BASH_REMATCH[0]} str="${str:${#token}}" token="${token}"