(import /src/calc) (import /src/operations) (import /src/adverbs) (def dictionary {"+" operations/add "-" operations/sub "*" operations/mul "x" operations/mul "%" operations/div "sqrt" operations/sqrt ">" operations/gt "<" operations/lt ">=" operations/gte "<=" operations/lte "=" operations/eq "cmp" operations/cmp "/" adverbs/distribute-dyad "!" adverbs/apply-quotation "@" adverbs/wrap-stack "swap" adverbs/swap "slurp" adverbs/slurp "slurpl" adverbs/slurp-left "slurpr" adverbs/slurp "c" adverbs/clear-stack}) (defn handle-parens [& patt] [:parens (string ;patt)]) (defn handle-brackets [& patt] (calc/wrap ;patt)) (defn handle-float [patt] (:new calc/Float (scan-number patt))) (defn handle-int [patt] (:new calc/Int (scan-number patt))) (defn handle-word [patt] (or (dictionary patt) (errorf "syntax error: unknown word %s" patt))) (def- peg (peg/compile ~{:main (any (+ :s+ :brackets :token)) :brackets (cmt (* "[" :main "]") ,handle-brackets) :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))