aboutsummaryrefslogtreecommitdiff
path: root/bash/env.sh
blob: 9595aa25faa810483de8a7208fcf19ea29abbc95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#
# mal (Make a Lisp) environment definition
#

if [ -z "${__mal_env_included__}" ]; then
__mal_env_included=true

source $(dirname $0)/types.sh

# Any environment is a hash_map with an __outer__ key that refers to
# a parent environment (or nil)
ENV () {
    r=
    _hash_map
    local env="${r}"
    if [[ "${1}" ]]; then
        outer="${1}"; shift
        _assoc! "${env}" "__outer__" "${outer}"
    else
        _assoc! "${env}" "__outer__" "${__nil}"
    fi
    r="${env}"

    if [[ "${1}" && "${@}" ]]; then
        local binds=(${ANON["${1}"]}); shift
        local idx=0
        while [[ "${binds["${idx}"]}" ]]; do
            local fp="${ANON["${binds["${idx}"]}"]}"
            if [[ "${fp}" == "&" ]]; then
                idx=$(( idx + 1 ))
                fp="${ANON["${binds["${idx}"]}"]}"
                _list "${@}"
                _assoc! "${env}" "${fp}" "${r}"
                break
            else
                _assoc! "${env}" "${fp}" "${1}"
                shift
                idx=$(( idx + 1 ))
            fi
        done
    fi
    r="${env}"
}

# Find the environment with the key set and return the environment
ENV_FIND () {
    if _contains? "${1}" "${ANON["${2}"]}"; then
        r="${1}"
    else
        local obj="${ANON["${1}"]}"
        eval local outer="\${${obj}["__outer__"]}"
        if [[ "${outer}" && "${outer}" != "${__nil}" ]]; then
            ENV_FIND "${outer}" "${2}"
        else
            r=
        fi
    fi
}

# Find the environment with the key set and return the value of the
# key in that environment. If no environment contains the key then
# return an error
ENV_GET () {
    ENV_FIND "${1}" "${2}"
    local env="${r}"
    local key="${ANON["${2}"]}"
    if [[ "${r}" ]]; then
        local obj="${ANON["${env}"]}"
        eval r="\${${obj}["${key}"]}"
    else
        _error "'${key}' not found"
    fi
}

ENV_SET () {
    local key="${ANON["${2}"]}"
    _assoc! "${1}" "${key}" "${3}"
}

fi