diff options
Diffstat (limited to 'bash/stepA_more.sh')
| -rwxr-xr-x | bash/stepA_more.sh | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/bash/stepA_more.sh b/bash/stepA_more.sh index 605ca7f..d968942 100755 --- a/bash/stepA_more.sh +++ b/bash/stepA_more.sh @@ -4,12 +4,12 @@ INTERACTIVE=${INTERACTIVE-yes} source $(dirname $0)/reader.sh source $(dirname $0)/printer.sh -source $(dirname $0)/core.sh source $(dirname $0)/env.sh +source $(dirname $0)/core.sh # READ: read and parse input READ () { - READLINE + [ "${1}" ] && r="${1}" || READLINE READ_STR "${r}" } @@ -36,7 +36,7 @@ QUASIQUOTE () { if [[ "${ANON["${a00}"]}" == "splice-unquote" ]]; then _symbol concat; local a="${r}" _nth "${a0}" 1; local b="${r}" - rest "${1}" + _rest "${1}" QUASIQUOTE "${r}"; local c="${r}" _list "${a}" "${b}" "${c}" return @@ -45,7 +45,7 @@ QUASIQUOTE () { fi _symbol cons; local a="${r}" QUASIQUOTE "${a0}"; local b="${r}" - rest "${1}" + _rest "${1}" QUASIQUOTE "${r}"; local c="${r}" _list "${a}" "${b}" "${c}" return @@ -68,7 +68,7 @@ MACROEXPAND () { while IS_MACRO_CALL "${ast}" "${env}"; do _nth "${ast}" 0; local a0="${r}" ENV_GET "${env}" "${ANON["${a0}"]}"; local mac="${ANON["${r}"]}" - rest "${ast}" + _rest "${ast}" ${mac%%@*} ${ANON["${r}"]} ast="${r}" done @@ -184,7 +184,7 @@ EVAL () { _slice "${ast}" 1 $(( ${r} - 2 )) EVAL_AST "${r}" "${env}" [[ "${__ERROR}" ]] && r= && return 1 - last "${ast}" + _last "${ast}" ast="${r}" # Continue loop ;; @@ -211,8 +211,8 @@ EVAL () { *) EVAL_AST "${ast}" "${env}" [[ "${__ERROR}" ]] && r= && return 1 local el="${r}" - first "${el}"; local f="${ANON["${r}"]}" - rest "${el}"; local args="${ANON["${r}"]}" + _first "${el}"; local f="${ANON["${r}"]}" + _rest "${el}"; local args="${ANON["${r}"]}" #echo "invoke: [${f}] ${args}" if [[ "${f//@/ }" != "${f}" ]]; then set -- ${f//@/ } @@ -244,37 +244,22 @@ PRINT () { ENV; REPL_ENV="${r}" REP () { r= - READ_STR "${1}" + READ "${1}" || return 1 EVAL "${r}" "${REPL_ENV}" PRINT "${r}" } +# core.sh: defined using bash _fref () { _function "${2} \"\${@}\""; ENV_SET "${REPL_ENV}" "${1}" "${r}"; } - -# Import types functions for n in "${!core_ns[@]}"; do _fref "${n}" "${core_ns["${n}"]}"; done - -readline () { - READLINE "${ANON["${1}"]}" && _string "${r}" || r="${__nil}"; -} -_fref "readline" readline -read_string () { READ_STR "${ANON["${1}"]}"; } -_fref "read-string" read_string _eval () { EVAL "${1}" "${REPL_ENV}"; } _fref "eval" _eval -slurp () { - local lines - mapfile lines < "${ANON["${1}"]}" - local text="${lines[*]}"; text=${text//$'\n' /$'\n'} - _string "${text}" -} -_fref "slurp" slurp -# Defined using the language itself +# core.mal: defined using the language itself REP "(def! not (fn* (a) (if a false true)))" +REP "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" REP "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" REP "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) \`(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" -REP "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" if [[ "${1}" ]]; then echo "${@}" |
