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 | |
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 | |
31690700 JM |
63 | PRINT () { |
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 |
74 | declare -A REPL_ENV |
75 | REP () { | |
86b689f3 | 76 | r= |
70aff0c1 | 77 | READ "${1}" |
31690700 JM |
78 | EVAL "${r}" REPL_ENV |
79 | PRINT "${r}" | |
80 | } | |
81 | ||
8cb5cda4 JM |
82 | plus () { r=$(( ${ANON["${1}"]} + ${ANON["${2}"]} )); _number "${r}"; } |
83 | minus () { r=$(( ${ANON["${1}"]} - ${ANON["${2}"]} )); _number "${r}"; } | |
84 | multiply () { r=$(( ${ANON["${1}"]} * ${ANON["${2}"]} )); _number "${r}"; } | |
85 | divide () { r=$(( ${ANON["${1}"]} / ${ANON["${2}"]} )); _number "${r}"; } | |
86 | ||
87 | REPL_ENV["+"]=plus | |
88 | REPL_ENV["-"]=minus | |
89 | REPL_ENV["__STAR__"]=multiply | |
90 | REPL_ENV["/"]=divide | |
31690700 | 91 | |
86b689f3 JM |
92 | # repl loop |
93 | while true; do | |
94 | READLINE "user> " || exit "$?" | |
95 | [[ "${r}" ]] && REP "${r}" && echo "${r}" | |
96 | done |