Merge pull request #372 from bjh21/bjh21-empty-hashmap
[jackhill/mal.git] / bash / step2_eval.sh
CommitLineData
7838e339 1#!/usr/bin/env bash
31690700 2
31690700 3source $(dirname $0)/reader.sh
ea81a808 4source $(dirname $0)/printer.sh
31690700 5
86b689f3 6# read
31690700 7READ () {
8cb5cda4 8 [ "${1}" ] && r="${1}" || READLINE
31690700
JM
9 READ_STR "${r}"
10}
11
86b689f3 12# eval
31690700
JM
13EVAL_AST () {
14 local ast="${1}" env="${2}"
15 #_pr_str "${ast}"; echo "EVAL_AST '${ast}:${r} / ${env}'"
16 _obj_type "${ast}"; local ot="${r}"
17 case "${ot}" in
18 symbol)
19 local val="${ANON["${ast}"]}"
20 eval r="\${${env}["${val}"]}"
21 [ "${r}" ] || _error "'${val}' not found" ;;
22 list)
ea81a808 23 _map_with_type _list EVAL "${ast}" "${env}" ;;
31690700 24 vector)
ea81a808 25 _map_with_type _vector EVAL "${ast}" "${env}" ;;
31690700 26 hash_map)
33d33bb3 27 local res="" key= val="" hm="${ANON["${ast}"]}"
ea81a808 28 _hash_map; local new_hm="${r}"
31690700
JM
29 eval local keys="\${!${hm}[@]}"
30 for key in ${keys}; do
31 eval val="\${${hm}[\"${key}\"]}"
32 EVAL "${val}" "${env}"
ea81a808 33 _assoc! "${new_hm}" "${key}" "${r}"
31690700
JM
34 done
35 r="${new_hm}" ;;
36 *)
37 r="${ast}" ;;
38 esac
39}
40
31690700
JM
41EVAL () {
42 local ast="${1}" env="${2}"
43 r=
44 [[ "${__ERROR}" ]] && return 1
45 #_pr_str "${ast}"; echo "EVAL '${r} / ${env}'"
46 _obj_type "${ast}"; local ot="${r}"
47 if [[ "${ot}" != "list" ]]; then
48 EVAL_AST "${ast}" "${env}"
49 return
50 fi
51
52 # apply list
5bbc7a1f
JM
53 _empty? "${ast}" && r="${ast}" && return
54
31690700
JM
55 EVAL_AST "${ast}" "${env}"
56 [[ "${__ERROR}" ]] && return 1
57 local el="${r}"
8cb5cda4
JM
58 _first "${el}"; local f="${r}"
59 _rest "${el}"; local args="${ANON["${r}"]}"
31690700
JM
60 #echo "invoke: ${f} ${args}"
61 eval ${f} ${args}
62}
63
86b689f3 64# print
31690700
JM
65PRINT () {
66 if [[ "${__ERROR}" ]]; then
67 _pr_str "${__ERROR}" yes
68 r="Error: ${r}"
69 __ERROR=
70 else
71 _pr_str "${1}" yes
72 fi
73}
74
86b689f3 75# repl
31690700
JM
76declare -A REPL_ENV
77REP () {
86b689f3 78 r=
70aff0c1 79 READ "${1}"
31690700
JM
80 EVAL "${r}" REPL_ENV
81 PRINT "${r}"
82}
83
8cb5cda4
JM
84plus () { r=$(( ${ANON["${1}"]} + ${ANON["${2}"]} )); _number "${r}"; }
85minus () { r=$(( ${ANON["${1}"]} - ${ANON["${2}"]} )); _number "${r}"; }
86multiply () { r=$(( ${ANON["${1}"]} * ${ANON["${2}"]} )); _number "${r}"; }
87divide () { r=$(( ${ANON["${1}"]} / ${ANON["${2}"]} )); _number "${r}"; }
88
89REPL_ENV["+"]=plus
90REPL_ENV["-"]=minus
91REPL_ENV["__STAR__"]=multiply
92REPL_ENV["/"]=divide
31690700 93
86b689f3
JM
94# repl loop
95while true; do
96 READLINE "user> " || exit "$?"
97 [[ "${r}" ]] && REP "${r}" && echo "${r}"
98done