(use fugue)
(import /src/calc)
(defproto Symbol calc/Element
value {:init? true}
quoted? {:default false})
(extend-multi calc/make-element [:symbol] [s] (new-Symbol s))
(extend-multi calc/make-element [_] [v] v)
(defn handle-parens
[& patt]
[:parens (string ;patt)])
(defn handle-quotes
[& patt]
(calc/quote-wrap ;patt))
(defn handle-vectors
[& patt]
(calc/wrap ;patt))
(defn handle-float
[patt]
(calc/new-Float (scan-number patt)
:doc patt))
(defn handle-int
[patt]
(calc/new-Int (scan-number patt)
:doc patt))
(defn handle-word
[patt]
(cond
(index-of patt ["." "p" "s" "?" "??"]) [:special patt]
(string/has-prefix? "'" patt) (new-Symbol
(string/slice patt 1)
:quoted? true)
(new-Symbol patt
:quoted? false)))
(def- peg (peg/compile
~{:main (any (+ :s+ :quotes :vectors :token))
:quotes (cmt (* (set "({") :main (set ")}")) ,handle-quotes)
:vectors (cmt (* "[" :main "]") ,handle-vectors)
:number-part (some (+ :d "_"))
:float (cmt (<- (* (? "-") (? :number-part) "." :number-part)) ,handle-float)
:int (cmt (<- (* (? "-") :number-part)) ,handle-int)
:word (cmt (<- (some (if-not (+ :s (set "()[]{}")) 1))) ,handle-word)
:token (+ :float :int :word)}))
(defn parse
[str]
(peg/match peg str))