|
937 | 937 | (reduce #(conj %1 %2)
|
938 | 938 | {}
|
939 | 939 | maps)))
|
| 940 | + |
| 941 | +(defmacro binding |
| 942 | + "Establish thread-local bindings for the vars given. The bindings are guaranteed |
| 943 | + to clear once execution passes outside the scope of this block." |
| 944 | + [bindings & body] |
| 945 | + (when-not (and (vector? bindings) |
| 946 | + (even? (count bindings)) |
| 947 | + (pos? (count bindings))) |
| 948 | + (throw |
| 949 | + (ex-info "Expected an even number of bindings" |
| 950 | + {:bindings bindings}))) |
| 951 | + (let [vvar (first bindings) |
| 952 | + val (second bindings)] |
| 953 | + `(try |
| 954 | + (do |
| 955 | + (.push-bindings (var ~vvar) ~val) |
| 956 | + ~@(if (nthnext bindings 2) |
| 957 | + [(concat |
| 958 | + (list 'binding (vec (nthrest bindings 2))) |
| 959 | + body)] |
| 960 | + body)) |
| 961 | + (finally |
| 962 | + (.pop-bindings (var ~vvar)))))) |
| 963 | + |
| 964 | +(def |
| 965 | + ^{:doc "The default data readers used in reader macros. Overriding or |
| 966 | + attempting to change the root binding of this var will not |
| 967 | + change the default data readers."} |
| 968 | + default-data-readers |
| 969 | + (.--DATA-READERS basilisp.reader/ReaderContext)) |
| 970 | + |
| 971 | +(def |
| 972 | + ^{:doc "Data readers map which will be merged in to the default data |
| 973 | + reader map used by the reader. Mappings should be qualified |
| 974 | + symbols to functions taking one argument. The function will |
| 975 | + receive an unevaluated data structure and must return some |
| 976 | + value to the reader." |
| 977 | + :dynamic true} |
| 978 | + *data-readers* |
| 979 | + {}) |
| 980 | + |
| 981 | +(def |
| 982 | + ^{:doc "Resolver used for resolving namespace aliases when reading |
| 983 | + forms using read, read-string, etc." |
| 984 | + :dynamic true} |
| 985 | + *resolver* |
| 986 | + basilisp.lang.runtime/resolve-alias) |
| 987 | + |
| 988 | +(def ^:dynamic *in* sys/stdin) |
| 989 | +(def ^:dynamic *out* sys/stdout) |
| 990 | +(def ^:dynamic *err* sys/stderr) |
| 991 | + |
| 992 | +(defn read-string |
| 993 | + "Read a string of Basilisp code. |
| 994 | + |
| 995 | + Callers may bind a map of readers to *data-readers* to customize the |
| 996 | + data readers used reading this string. |
| 997 | + |
| 998 | + Note that read-string should not be used to read string input from |
| 999 | + untrusted sources." |
| 1000 | + ([s] |
| 1001 | + (read-string {} s)) |
| 1002 | + ([opts s] |
| 1003 | + (first (basilisp.reader/read-str s *resolver* *data-readers*)))) |
| 1004 | + |
| 1005 | +(defn read |
| 1006 | + "Read the next form from the stream. If no stream is specified, uses |
| 1007 | + the value currently bound to *in*. |
| 1008 | + |
| 1009 | + Callers may bind a map of readers to *data-readers* to customize the |
| 1010 | + data readers used reading this string. |
| 1011 | + |
| 1012 | + The stream must satisfy the interface of io.TextIOBase, but does not require |
| 1013 | + any pushback capabilities. The default basilisp.reader.StreamReader can wrap |
| 1014 | + any object implementing TextIOBase and provide pushback capabilities." |
| 1015 | + ([] |
| 1016 | + (read *in*)) |
| 1017 | + ([stream] |
| 1018 | + (read {} stream)) |
| 1019 | + ([opts stream] |
| 1020 | + (first (basilisp.reader/read stream *resolver* *data-readers*)))) |
| 1021 | + |
| 1022 | +(defn eval |
| 1023 | + "Evaluate a form (not a string) and return its result." |
| 1024 | + [form] |
| 1025 | + (let [ctx (basilisp.compiler.CompilerContext.) |
| 1026 | + module (.-module *ns*)] |
| 1027 | + (basilisp.compiler/compile-and-exec-form form |
| 1028 | + ctx |
| 1029 | + module |
| 1030 | + "<Eval Input>"))) |
0 commit comments