Merge pull request #281 from sebras/master
[jackhill/mal.git] / bash / env.sh
CommitLineData
ea81a808
JM
1#
2# mal (Make a Lisp) environment definition
3#
4
5if [ -z "${__mal_env_included__}" ]; then
6__mal_env_included=true
7
8source $(dirname $0)/types.sh
9
10# Any environment is a hash_map with an __outer__ key that refers to
11# a parent environment (or nil)
12ENV () {
13 r=
14 _hash_map
15 local env="${r}"
16 if [[ "${1}" ]]; then
17 outer="${1}"; shift
18 _assoc! "${env}" "__outer__" "${outer}"
19 else
20 _assoc! "${env}" "__outer__" "${__nil}"
21 fi
22 r="${env}"
23
24 if [[ "${1}" && "${@}" ]]; then
25 local binds=(${ANON["${1}"]}); shift
26 local idx=0
27 while [[ "${binds["${idx}"]}" ]]; do
28 local fp="${ANON["${binds["${idx}"]}"]}"
29 if [[ "${fp}" == "&" ]]; then
30 idx=$(( idx + 1 ))
31 fp="${ANON["${binds["${idx}"]}"]}"
32 _list "${@}"
33 _assoc! "${env}" "${fp}" "${r}"
34 break
35 else
36 _assoc! "${env}" "${fp}" "${1}"
37 shift
38 idx=$(( idx + 1 ))
39 fi
40 done
41 fi
42 r="${env}"
43}
44
45# Find the environment with the key set and return the environment
46ENV_FIND () {
b8ee29b2 47 if _contains? "${1}" "${ANON["${2}"]}"; then
ea81a808
JM
48 r="${1}"
49 else
50 local obj="${ANON["${1}"]}"
51 eval local outer="\${${obj}["__outer__"]}"
52 if [[ "${outer}" && "${outer}" != "${__nil}" ]]; then
53 ENV_FIND "${outer}" "${2}"
54 else
55 r=
56 fi
57 fi
58}
59
60# Find the environment with the key set and return the value of the
61# key in that environment. If no environment contains the key then
62# return an error
63ENV_GET () {
64 ENV_FIND "${1}" "${2}"
65 local env="${r}"
b8ee29b2 66 local key="${ANON["${2}"]}"
ea81a808
JM
67 if [[ "${r}" ]]; then
68 local obj="${ANON["${env}"]}"
b8ee29b2 69 eval r="\${${obj}["${key}"]}"
ea81a808 70 else
b8ee29b2 71 _error "'${key}' not found"
ea81a808
JM
72 fi
73}
74
75ENV_SET () {
b8ee29b2
JM
76 local key="${ANON["${2}"]}"
77 _assoc! "${1}" "${key}" "${3}"
ea81a808
JM
78}
79
80fi