Guest User

array dsl solution

a guest
Apr 15th, 2013
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;; load up a couple of string and io functions
  2. (use '[clojure.string :only (split-lines split trim)])
  3. (use 'clojure.java.io)
  4.  
  5.  
  6. (defn split-by-spc [str]
  7.   (split str #" "))
  8.  
  9. ;; split into separate strings by newline, then trim and split each line by spaces
  10. (defn tokenize-prog [str]
  11.   (map (comp split-by-spc trim) (split-lines str)))
  12.  
  13.  
  14. ;; expands to a fast unboxed-array read with type hints
  15. (defmacro fast-aget
  16.   ([hint array idx]
  17.     `(aget ~(vary-meta array assoc :tag hint) ~idx))
  18.   ([hint array idx & idxs]
  19.     `(let [a# (aget ~(vary-meta array assoc :tag 'objects) ~idx)]
  20.        (fast-aget ~hint a# ~@idxs))))
  21.  
  22.  
  23. ;; expands to a fast unboxed-array set with type hints
  24. (defmacro fast-aset [hint array & idxsv]
  25.   (let [hints '{doubles double ints int}
  26.         [v idx & sxdi] (reverse idxsv)
  27.         idxs (reverse sxdi)
  28.         v (if-let [h (hints hint)] (list h v) v)
  29.         nested-array (if (seq idxs)
  30.                        `(fast-aget ~'objects ~array ~@idxs)
  31.                         array)
  32.         a-sym (with-meta (gensym "a") {:tag hint})]
  33.       `(let [~a-sym ~nested-array]
  34.          (aset ~a-sym ~idx ~v))))
  35.  
  36.  
  37.  
  38. ;; case dispatch on 'opcode' (SetCol, SetRow, etc)
  39. ;; and return quoted code that, when evaluated, performs the operation
  40. (defn compile-code [[opcode op1 op2]]
  41.   ;; parse integers from string
  42.   (let [op1 (read-string op1)
  43.         op2 (if op2 (read-string op2) )]
  44.     (case opcode
  45.  
  46.       ;; loop over column and set values
  47.       "SetCol" ` (let [~'x (int ~op1)]
  48.                    (dotimes [~'y (int 256)]
  49.                      (fast-aset ~'ints ~'matrix ~'y ~'x ~op2)))
  50.  
  51.       ;; loop over row
  52.       "SetRow" `(let [~'y (int ~op1)]
  53.                   (dotimes [~'x (int 256)]
  54.                     (fast-aset ~'ints ~'matrix ~'y ~'x ~op2)))
  55.  
  56.       ;; sum values in column and print
  57.       "QueryCol" `(println (let [~'x (int ~op1)]
  58.                              (loop [~'sum (int 0)  ~'y 0]
  59.                                (if (>= ~'y (int 256))
  60.                                  ~'sum
  61.                                  (recur (unchecked-add ~'sum (fast-aget ~'ints ~'matrix ~'y ~'x))
  62.                                         (unchecked-inc ~'y))))))
  63.  
  64.       ;; sum values in row and print
  65.       "QueryRow" `(println (let [~'y (int ~op1)]
  66.                              (loop [~'sum (int 0)  ~'x (int 0)]
  67.                                (if (>= ~'x (int 256))
  68.                                  ~'sum
  69.                                  (recur (unchecked-add ~'sum (fast-aget ~'ints ~'matrix ~'y ~'x))
  70.                                         (unchecked-inc ~'x)))))))))
  71.  
  72.  
  73.  
  74. ;; get lines of file into list
  75. (defn get-lines [file]
  76.   (with-open [rdr (clojure.java.io/reader file)]
  77.         (reduce conj [] (line-seq rdr))))
  78.  
  79. ;; compile array dsl into clojure code and evaluate
  80. ;; result of compilation will be something like
  81. ;;   (let [matrix ...]
  82. ;;        array loops and stuff
  83. ;;        ... )
  84. ;;
  85.  
  86. (defn compile-array-dsl-file [file]
  87.   (let [lines (get-lines file)]
  88.     (eval
  89.      `(let [~'matrix (make-array Integer/TYPE 256 256)]
  90.         ~@(map (comp compile-code split-by-spc) lines)))))
  91.  
  92. (compile-array-dsl-file (first *command-line-args*))
  93.  
  94. (System/exit 0)
Advertisement
Add Comment
Please, Sign In to add comment