Commit | Line | Data |
---|---|---|
7838e339 | 1 | #!/usr/bin/env bash |
31690700 | 2 | |
31690700 | 3 | source $(dirname $0)/reader.sh |
ea81a808 | 4 | source $(dirname $0)/printer.sh |
31690700 | 5 | |
86b689f3 | 6 | # read |
31690700 | 7 | READ () { |
8cb5cda4 | 8 | [ "${1}" ] && r="${1}" || READLINE |
31690700 JM |
9 | READ_STR "${r}" |
10 | } | |
11 | ||
86b689f3 | 12 | # eval |
31690700 JM |
13 | EVAL_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 |
41 | EVAL () { |
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 | |
31690700 JM |
65 | PRINT () { |
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 |
76 | declare -A REPL_ENV |
77 | REP () { | |
86b689f3 | 78 | r= |
70aff0c1 | 79 | READ "${1}" |
31690700 JM |
80 | EVAL "${r}" REPL_ENV |
81 | PRINT "${r}" | |
82 | } | |
83 | ||
8cb5cda4 JM |
84 | plus () { r=$(( ${ANON["${1}"]} + ${ANON["${2}"]} )); _number "${r}"; } |
85 | minus () { r=$(( ${ANON["${1}"]} - ${ANON["${2}"]} )); _number "${r}"; } | |
86 | multiply () { r=$(( ${ANON["${1}"]} * ${ANON["${2}"]} )); _number "${r}"; } | |
87 | divide () { r=$(( ${ANON["${1}"]} / ${ANON["${2}"]} )); _number "${r}"; } | |
88 | ||
89 | REPL_ENV["+"]=plus | |
90 | REPL_ENV["-"]=minus | |
91 | REPL_ENV["__STAR__"]=multiply | |
92 | REPL_ENV["/"]=divide | |
31690700 | 93 | |
86b689f3 JM |
94 | # repl loop |
95 | while true; do | |
96 | READLINE "user> " || exit "$?" | |
97 | [[ "${r}" ]] && REP "${r}" && echo "${r}" | |
98 | done |