Merge pull request #15 from joelpickup/master
[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
JM
26 hash_map)
27 local res="" 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
53 EVAL_AST "${ast}" "${env}"
54 [[ "${__ERROR}" ]] && return 1
55 local el="${r}"
8cb5cda4
JM
56 _first "${el}"; local f="${r}"
57 _rest "${el}"; local args="${ANON["${r}"]}"
31690700
JM
58 #echo "invoke: ${f} ${args}"
59 eval ${f} ${args}
60}
61
86b689f3 62# print
31690700
JM
63PRINT () {
64 if [[ "${__ERROR}" ]]; then
65 _pr_str "${__ERROR}" yes
66 r="Error: ${r}"
67 __ERROR=
68 else
69 _pr_str "${1}" yes
70 fi
71}
72
86b689f3 73# repl
31690700
JM
74declare -A REPL_ENV
75REP () {
86b689f3 76 r=
70aff0c1 77 READ "${1}"
31690700
JM
78 EVAL "${r}" REPL_ENV
79 PRINT "${r}"
80}
81
8cb5cda4
JM
82plus () { r=$(( ${ANON["${1}"]} + ${ANON["${2}"]} )); _number "${r}"; }
83minus () { r=$(( ${ANON["${1}"]} - ${ANON["${2}"]} )); _number "${r}"; }
84multiply () { r=$(( ${ANON["${1}"]} * ${ANON["${2}"]} )); _number "${r}"; }
85divide () { r=$(( ${ANON["${1}"]} / ${ANON["${2}"]} )); _number "${r}"; }
86
87REPL_ENV["+"]=plus
88REPL_ENV["-"]=minus
89REPL_ENV["__STAR__"]=multiply
90REPL_ENV["/"]=divide
31690700 91
86b689f3
JM
92# repl loop
93while true; do
94 READLINE "user> " || exit "$?"
95 [[ "${r}" ]] && REP "${r}" && echo "${r}"
96done