(import /src/calc) (import /src/operations) (import /src/adverbs) (import /src/compose) (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 "pow" operations/pow "distribute" adverbs/distribute "/" adverbs/distribute "apply" adverbs/apply-quotation "!" adverbs/apply-quotation "@" adverbs/wrap-stack "swap" adverbs/swap "slurp" adverbs/slurp "slurpl" adverbs/slurp-left "slurpr" adverbs/slurp "c" adverbs/clear-stack "fill" adverbs/fill "dup" adverbs/dup "arity" adverbs/arity "shape" adverbs/shape "sqr" compose/square}) (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] (:new calc/Float (scan-number patt) :doc patt)) (defn handle-int [patt] (:new calc/Int (scan-number patt) :doc patt)) (defn handle-word [patt] (cond (index-of patt ["." "p" "s" "?" "??"]) [:special patt] true (or (dictionary patt) (errorf "syntax error: unknown word %s" patt)))) (def- peg (peg/compile ~{:main (any (+ :s+ :quotes :vectors :token)) :quotes (cmt (* "(" :main ")") ,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))