Guest User

Untitled

a guest
Jul 5th, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;; Parse tables and stuff for infix notation for mathematical expressions
  2.  
  3. (defn power [m e]  
  4.   ;; m raised to the power e, whether intified or floaty
  5.   (if (or (float? m) (float? e))
  6.     (Math/pow m e)    
  7.     (do (defn _pow [m e]
  8.           (cond (<= e 0) 1
  9.                 (zero? (mod e 2)) (let [a (_pow m (/ e 2))] (*' a a))
  10.                 :else (*' m (_pow m (- e 1)))))
  11.         (_pow m e))))
  12.  
  13. (defn factorial [n]
  14.   (if (<= n 0)
  15.     1
  16.     (*' n (factorial (- n 1)))))
  17.  
  18.  
  19. (def lex-table (sorted-map :int "[0-9]+"
  20.                            :word "[_a-zA-Z]+"
  21.                            :float "[0-9]*\\.[0-9]+"
  22.                            :op1 "\\^"
  23.                            :op2  "[/*]"
  24.                            :op3  "[+-]"
  25.                            :lparens "\\("                
  26.                            :rparens "\\)"))
  27.  
  28. (def kword
  29.   ;;Java Math functions are decidedly second-class citizens
  30.   {"sin" #(Math/sin %)
  31.    "cos" #(Math/cos %)
  32.    "tan" #(Math/tan %)
  33.    "asin" #(Math/asin %)
  34.    "acos" #(Math/acos %)
  35.    "atan" #(Math/atan %)
  36.    "fact" factorial
  37.    "exp"  #(Math/exp %)
  38.    "log"  #(Math/log %)
  39.    })
  40.  
  41. (def const
  42.   {"pi"   (Math/PI)
  43.    "e"    (Math/E)  
  44.   })
  45.  
  46. (def operat
  47.   {"*" *'
  48.    "/" /
  49.    "+" +'
  50.    "-" -
  51.    "^" power
  52.    })
  53.  
  54. ;; parse-table - first argument is the initial top-level tag that everything should match to
  55.  
  56.  
  57. (defn right-op [args]
  58.   (let [foo (list  (first args)
  59.                    (if (= 2 (count (second args)))
  60.                      (rest (second args))
  61.                      (right-op (rest (second args)))))]
  62.     (println "right-op" (first (second args)) foo)
  63.     (apply (get operat (first (second args))) foo)))
  64.  
  65.  
  66. (def parse-table [:exp
  67.                   {:exp {
  68.                          [:term :rexp]   right-op
  69.                                            
  70.                          
  71.                          [:term]          (fn [args]
  72.                                             (println ":term" args)
  73.                                             (first args))
  74.                          }
  75.                    
  76.                    :rexp {[:op3 :term :rexp] (fn [args]
  77.                                                (println ":rexp" args)
  78.                                                args)
  79.  
  80.                           [:op3 :term] (fn [args]
  81.                                          (list (first args) (second args)))
  82.                           }
  83.                    
  84.                    :term {[:number :rterm]    right-op
  85.                          
  86.                           [:number]      (fn [args]
  87.                                            (first args))
  88.                           }
  89.                    
  90.                    :rterm {[:op2 :number :rterm]   (fn [args]
  91.                                                      (println "rterm:" args)
  92.                                                      (list (first args) (second args) (get args 2)))
  93.                            
  94.                            [:op2 :number]          (fn [args]
  95.                                                      (println "rterm2:" args)
  96.                                                      (list (first args) (second args)))
  97.                            }
  98.                    
  99.                    :number { [:float]    (fn [x] (Double/parseDouble (first x)))
  100.                              [:int]      (fn [x] (Integer/parseInt (first x)))
  101.                              [:lparens :exp :rparens] (fn [args] (println "paren:" args) (second args))
  102.                              [:word :lparens :exp :rparens] #((kword (first %)) (nth % 2))
  103.                              [:word :lparens :rparens]      #(const (first %))
  104.                              }
  105.                    }])
Add Comment
Please, Sign In to add comment