Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;; compiles a simple array dsl to clojure code
- ;
- ; ; Each command operates on an implicit global 2d array of 256 rows and 256 columns
- ; SetCol 32 20 (set each slot in the 32nd column to 20)
- ; SetRow 20 12 (set each slot in the 20th row to 12)
- ; QueryRow 20 (sum each slot in the 20th row and print result)
- ; QueryCol 12 (sum each slot in the 12th column and print result)
- ;; load up a couple of string and io functions
- (use '[clojure.string :only (split-lines split trim)])
- (use 'clojure.java.io)
- (defn split-by-spc [str]
- (split str #" "))
- ;; split into separate strings by newline, then trim and split each line by spaces
- (defn tokenize-prog [str]
- (map (comp split-by-spc trim) (split-lines str)))
- ;; expands to a fast unboxed-array read with type hints
- (defmacro fast-aget
- ([hint array idx]
- `(aget ~(vary-meta array assoc :tag hint) ~idx))
- ([hint array idx & idxs]
- `(let [a# (aget ~(vary-meta array assoc :tag 'objects) ~idx)]
- (fast-aget ~hint a# ~@idxs))))
- ;; expands to a fast unboxed-array set with type hints
- (defmacro fast-aset [hint array & idxsv]
- (let [hints '{doubles double ints int}
- [v idx & sxdi] (reverse idxsv)
- idxs (reverse sxdi)
- v (if-let [h (hints hint)] (list h v) v)
- nested-array (if (seq idxs)
- `(fast-aget ~'objects ~array ~@idxs)
- array)
- a-sym (with-meta (gensym "a") {:tag hint})]
- `(let [~a-sym ~nested-array]
- (aset ~a-sym ~idx ~v))))
- ;; case dispatch on 'opcode' (SetCol, SetRow, etc)
- ;; and return quoted code that, when evaluated, performs the operation
- (defn compile-code [[opcode op1 op2]]
- ;; parse integers from string
- (let [op1 (read-string op1)
- op2 (if op2 (read-string op2) )]
- (case opcode
- ;; loop over column and set values
- "SetCol" ` (let [~'x (int ~op1)]
- (dotimes [~'y (int 256)]
- (fast-aset ~'ints ~'matrix ~'y ~'x ~op2)))
- ;; loop over row
- "SetRow" `(let [~'y (int ~op1)]
- (dotimes [~'x (int 256)]
- (fast-aset ~'ints ~'matrix ~'y ~'x ~op2)))
- ;; sum values in column and print
- "QueryCol" `(println (let [~'x (int ~op1)]
- (loop [~'sum (int 0) ~'y 0]
- (if (>= ~'y (int 256))
- ~'sum
- (recur (unchecked-add ~'sum (fast-aget ~'ints ~'matrix ~'y ~'x))
- (unchecked-inc ~'y))))))
- ;; sum values in row and print
- "QueryRow" `(println (let [~'y (int ~op1)]
- (loop [~'sum (int 0) ~'x (int 0)]
- (if (>= ~'x (int 256))
- ~'sum
- (recur (unchecked-add ~'sum (fast-aget ~'ints ~'matrix ~'y ~'x))
- (unchecked-inc ~'x)))))))))
- ;; get lines of file into list
- (defn get-lines [file]
- (with-open [rdr (clojure.java.io/reader file)]
- (reduce conj [] (line-seq rdr))))
- ;; compile array dsl into clojure code and evaluate
- ;; result of compilation will be something like
- ;; (let [matrix ...]
- ;; array loops and stuff
- ;; ... )
- ;;
- (defn compile-array-dsl-file [file]
- (let [lines (get-lines file)]
- (eval
- `(let [~'matrix (make-array Integer/TYPE 256 256)]
- ~@(map (comp compile-code split-by-spc) lines)))))
- (compile-array-dsl-file "some-file.txt")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement