Last active
June 26, 2016 13:27
-
-
Save miner/5224709 to your computer and use it in GitHub Desktop.
An infix data-reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns miner.infix) | |
;; Inspired by the excellent book "The Joy of Clojure". | |
;; http://fogus.me/fun/unfix/infix-src.html | |
;; | |
;; Converted to be used as a data-reader by Steve Miner. The main change is to preserve | |
;; the prefix forms rather than calculating the result. Also, the reader gets symbols, not | |
;; the actual functions. | |
(def && #(and % %2)) | |
(def || #(or % %2)) | |
(def ops '[- + * / < > && || =]) | |
(def rank (zipmap ops (iterate inc 1))) | |
(def op? rank) | |
(defn infix | |
[[a b & [c d & m]]] | |
(cond | |
(vector? a) (recur (list* (infix a) b c d m)) | |
(vector? c) (recur (list* a b (infix c) d m)) | |
(op? b) (if (and d (< (rank b 0) (rank d 0))) | |
(recur (list a b (infix (list* c d m)))) | |
(recur (list* (list b a c) d m))) | |
:else a)) | |
(def infix-reader infix) | |
(comment | |
(binding [*data-readers* {'x/infix #'infix-reader}] | |
(read-string "#x/infix [2 + 3 * 4]")) | |
;=> (+ 2 (* 3 4)) | |
(binding [*data-readers* {'x/infix #'infix-reader}] | |
(read-string "#x/infix [2 * b + 10 * [7 - a]]")) | |
;=> (+ (* 2 b) (* 10 (- 7 a))) | |
;; for any kind of user input it would be better to use clojure.edn | |
(clojure.edn/read-string {:readers {'x/infix #'infix-reader}} "#x/infix [2 * b + 10 * [7 - a]]") | |
;=> (+ (* 2 b) (* 10 (- 7 a))) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment