Advertisement
Guest User

Untitled

a guest
May 15th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defn -return [value tail] {:value value :tail tail})
  2. (def -valid? boolean)
  3. (def -value :value)
  4. (def -tail :tail)
  5.  
  6. (defn _empty [value] (partial -return value))
  7.  
  8. (defn _char [p]
  9.   (fn [[c & cs]]
  10.     (if (and c (p c)) (-return c cs))))
  11.  
  12. (defn _map [f]
  13.   (fn [result]
  14.     (if (-valid? result)
  15.       (-return (f (-value result)) (-tail result)))))
  16.  
  17. (defn _combine [f a b]
  18.   (fn [str]
  19.     (let [ar ((force a) str)]
  20.       (if (-valid? ar)
  21.         ((_map (partial f (-value ar)))
  22.          ((force b) (-tail ar)))))))
  23.  
  24. (defn _either [a b]
  25.   (fn [str]
  26.     (let [ar ((force a) str)]
  27.       (if (-valid? ar) ar ((force b) str)))))
  28.  
  29. (defn _parser [p]
  30.   (fn [input]
  31.     (-value ((_combine (fn [v _] v) p (_char #{\u0000})) (str input \u0000)))))
  32.  
  33.  
  34.  
  35. ; Second level of abstraction
  36. (defn +char [chars] (_char (set chars)))
  37.  
  38. (defn +char-not [chars] (_char (comp not (set chars))))
  39.  
  40. (defn +map [f parser] (comp (_map f) parser))
  41.  
  42. (def +parser _parser)
  43.  
  44. (def +ignore (partial +map (constantly 'ignore)))
  45.  
  46. (defn iconj [coll value]
  47.   (if (= value 'ignore) coll (conj coll value)))
  48.  
  49. (defn +seq [& ps]
  50.   (reduce (partial _combine iconj) (_empty []) ps))
  51.  
  52. (defn +seqf [f & ps] (+map (partial apply f) (apply +seq ps)))
  53.  
  54. (defn +seqn [n & ps] (apply +seqf (fn [& vs] (nth vs n)) ps))
  55.  
  56. (defn +or [p & ps]
  57.   (reduce (partial _either) p ps))
  58.  
  59. (defn +opt [p]
  60.   (+or p (_empty nil)))
  61.  
  62. (defn +star [p]
  63.   (letfn [(rec [] (+or (+seqf cons p (delay (rec))) (_empty ())))] (rec)))
  64.  
  65. (defn +plus [p] (+seqf cons p (+star p)))
  66.  
  67. (defn +str [p] (+map (partial apply str) p))
  68.  
  69.  
  70.  
  71. ; Third level of abstraction (READ-EXPRESSION FUNCTION)
  72. (def read-expression
  73.   (let
  74.     [
  75.      *all-chars (mapv char (range 0 128))
  76.  
  77.      *digit (+char "0123456789")
  78.      *number (+map read-string (+str (+plus (+or *digit (+char "-.")))))
  79.  
  80.      *space (+char (apply str (filter #(Character/isWhitespace (char %)) *all-chars)))
  81.      *ws (+ignore (+star *space))
  82.  
  83.      *negate (+seqf (constantly 'negate) (+char "n") (+char "e") (+char "g") (+char "a") (+char "t") (+char "e"))
  84.      *operation (+map symbol (+str (+plus (+char "+-/*"))))
  85.  
  86.      *variable (+map symbol (+str (+plus (+char "xyzXYZ"))))
  87.      ]
  88.  
  89.     (letfn [
  90.             (*seq [begin p end]
  91.               (+seqn 1 (+char begin) (+opt (+seqf cons *ws p (+star (+seqn 1 (+char " ") *ws p)))) *ws (+char end)))
  92.  
  93.             (*list [] (*seq "(" (delay (*value)) ")"))
  94.  
  95.             (*value [] (+or *negate *number *variable (*list) *operation))
  96.             ]
  97.       (+parser (+seqn 0 *ws (*value) *ws)))))
  98.  
  99.  
  100. ; Functions
  101. (def div #(/ (double %1) %2))
  102. (defn hyperbolic [op] #(div (op (Math/exp %) (Math/exp (- %))) 2))
  103. (def sqrt #(Math/sqrt (Math/abs (double %))))
  104. (def square #(* % %))
  105. (def sinh (hyperbolic -))
  106. (def cosh (hyperbolic +))
  107.  
  108. ; Proto-methods
  109. (defn proto-get [obj key]
  110.   (cond
  111.     (contains? obj key) (obj key)
  112.     (contains? obj :prototype) (proto-get (obj :prototype) key)
  113.     :else nil))
  114.  
  115. (defn proto-call [this key & args]
  116.   (apply (proto-get this key) this args))
  117.  
  118. (defn field [key]
  119.   (fn [this] (proto-get this key)))
  120.  
  121. ; Достаем метод и применяем к объекту и аргументам
  122. (defn method [key]
  123.   (fn [this & args] (apply proto-call this key args)))
  124.  
  125. (def evaluate (method :evaluate))
  126. (def toString (method :toString))
  127. (def toStringSuffix (method :toStringSuffix))
  128. (def diff (method :diff))
  129.  
  130. ; Classes
  131. (defn Constant [value]
  132.   {
  133.    :toString       (fn [_] (format "%.1f" value))
  134.    :toStringSuffix (fn [_] (format "%.1f" value))
  135.    :evaluate       (fn [_ _] value)
  136.    :diff           (fn [_ _] (Constant 0))
  137.    })
  138.  
  139. (def zero (Constant 0))
  140. (def one (Constant 1))
  141. (def two (Constant 2))
  142.  
  143. (def var-proto
  144.   (let [name (field :name)]
  145.     {
  146.      :toString       (fn [this] (name this))
  147.      :toStringSuffix (fn [this] (name this))
  148.      :evaluate       (fn [this keymap] (keymap (clojure.string/lower-case (first (name this)))))
  149.      :diff           (fn [this var] (if (= var (name this)) one zero))
  150.      }))
  151.  
  152. (defn Variable [name]
  153.   {
  154.    :prototype var-proto
  155.    :name      name
  156.    })
  157.  
  158. (def operation-proto
  159.   (let [diffFunc (field :diffFunc)
  160.         name (field :name)
  161.         op (field :op)
  162.         operands (field :operands)]
  163.     {
  164.      :toString       (fn [this]
  165.                        (str "(" (name this) " " (clojure.string/join " " (map toString (operands this))) ")"))
  166.  
  167.      :toStringSuffix (fn [this]
  168.                        (str "(" (clojure.string/join " " (map toStringSuffix (operands this))) " " (name this) ")"))
  169.  
  170.      :evaluate       (fn [this values]
  171.                        (apply (op this) (map #(evaluate % values) (operands this))))
  172.  
  173.      :diff           (fn [this var] (let [curArgs (operands this) a (first curArgs) b (last curArgs)]
  174.                                       (if (= (count curArgs) 2)
  175.                                         ((diffFunc this) a b (diff a var) (diff b var))
  176.                                         ((diffFunc this) a (diff a var)))))
  177.      }))
  178.  
  179. (defn operation-params [op name diffFunc]
  180.   {
  181.    :prototype operation-proto
  182.    :op        op
  183.    :name      name
  184.    :diffFunc  diffFunc
  185.    })
  186.  
  187. (defn operation [op name diffFunc]
  188.   (let [params-proto (operation-params op name diffFunc)]
  189.     (fn [& operands]
  190.       {
  191.        :prototype params-proto
  192.        :operands  (vec operands)
  193.        })))
  194.  
  195. (def Add (operation + "+" (fn [_ _ da db] (Add da db))))
  196.  
  197. (def Subtract (operation - "-" (fn [_ _ da db] (Subtract da db))))
  198.  
  199. (def Multiply (operation * "*" (fn [a b da db] (Add (Multiply da b) (Multiply db a)))))
  200.  
  201. (def Divide (operation
  202.               div "/" (fn [a b da db] (Divide (Subtract (Multiply b da)
  203.                                                         (Multiply a db))
  204.                                               (Multiply b b)))))
  205.  
  206. (def Negate (operation - "negate" (fn [_ da] (Subtract da))))
  207.  
  208. (def Square (operation square "square" (fn [a da] (Multiply two (Multiply a da)))))
  209.  
  210. (def Sqrt (operation sqrt "sqrt" (fn [a da] (Divide (Multiply da a)
  211.                                                     (Multiply
  212.                                                       two (Sqrt (Multiply (Square a) a)))))))
  213.  
  214. (declare Cosh)
  215.  
  216. (def Sinh (operation sinh "sinh" (fn [a da] (Multiply da (Cosh a)))))
  217.  
  218. (def Cosh (operation cosh "cosh" (fn [a da] (Multiply da (Sinh a)))))
  219.  
  220. (def ops
  221.   {'+      Add,
  222.    '-      Subtract,
  223.    '*      Multiply,
  224.    '/      Divide,
  225.    'negate Negate
  226.    'sqrt   Sqrt
  227.    'square Square
  228.    'sinh   Sinh
  229.    'cosh   Cosh
  230.    })
  231.  
  232. (defn parseSuffix [expr]
  233.   (cond
  234.     (number? expr) (Constant expr)
  235.     (symbol? expr) (Variable (str expr))
  236.     (seq? expr) (apply (ops (last expr)) (map parseSuffix (butlast expr)))))
  237.  
  238. (def parseObjectSuffix (comp parseSuffix read-expression))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement