Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn parse-args
- [args]
- (string/join ", " (for [arg args]
- (cond
- (map? arg) (let [{:keys [keys]} arg]
- (format "{ %s }" (parse-args keys)))
- :else arg))))
- (defn emit
- [x]
- (cond
- (list? x) (let [[op & args] x]
- (cond
- ('#{const var let} op) (format "%s %s = %s" op (first args) (emit (second args)))
- ('#{=>} op) (format "((%s) %s %s)" (parse-args (first args)) op (emit (second args)))
- ('#{function} op) (format "%s %s (%s) { %s }" op (first args)
- (parse-args (second args))
- (emit (apply list (into '[do] (rest (rest args))))))
- ('#{+ - == / ===} op) (format "(%s %s %s)" (emit (first args)) op (emit (second args)))
- ('#{new} op) (format "(%s %s(%s))" op (first args) (string/join ", " (map emit (rest args))))
- ('#{switch} op) (format "%s %s { %s default: %s }"
- op
- (emit (first args))
- (string/join "\n" (for [[k v] (partition 2 (butlast (rest args)))]
- (format "case %s: \n %s; \nbreak;\n" (emit k) (emit v))))
- (emit (last args)))
- ('#{do} op) (string/join ";\n" (concat (map emit args) [""]))
- ('#{return} op) (format "%s %s" op (string/join ", " (map emit args)))
- (and (symbol? op)
- (string/starts-with? op ".")) (format "%s%s(%s)" (emit (first args)) op (emit (second args)))
- :else (format "(%s(%s))" op (string/join ", " (map emit args)))
- ))
- (keyword? x) (format "'%s'" (name x))
- (string? x) (format "\"%s\"" x)
- (vector? x) (format "([%s])" (string/join ", " (map emit x)))
- (map? x) (format "({%s})" (string/join ", " (for [[k v] x] (string/join ": " [(emit k) (emit v)]))))
- :else (format "(%s)" x)))
- (deftest code
- (let []
- (fact
- (emit '0) => "(0)"
- (emit '(const x 44)) => "const x = (44)"
- (emit '(=> [x] x)) => "((x) => (x))"
- (emit '(+ 1 2)) => "((1) + (2))"
- (emit '(var myFoo (=> [x y] (+ x y)))) => "var myFoo = ((x, y) => ((x) + (y)))"
- (emit '(myFoo 1 2)) => "(myFoo((1), (2)))"
- (emit '(function myFn [a b] (return (+ a b)))) => "function myFn (a, b) { return ((a) + (b));\n }"
- (emit ':aaa) => "'aaa'"
- (emit '(const x (+ :xyz 33))) => "const x = ('xyz' + (33))"
- (emit '(const f (=> [{:keys [a]}] (+ a 55)))) => "const f = (({ a }) => ((a) + (55)))"
- (emit '(const f (=> [] (+ 55 0)))) => "const f = (() => ((55) + (0)))"
- (emit '[]) => "([])"
- (emit '[1 :a "b" (f c)]) => "([(1), 'a', \"b\", (f((c)))])"
- (emit '{:foo 33}) => "({'foo': (33)})"
- (emit '(.get x 33)) => "(x).get((33))"
- (emit '(.values Object {:a 33})) => "(Object).values(({'a': (33)}))"
- (emit '(do 1 2)) => "(1);\n(2);\n"
- (emit '(new Set [1 2])) => "(new Set(([(1), (2)])))"
- (emit '(function myFn
- [a b]
- (const x (+ a b))
- (.log console x)
- (return x)))
- => "function myFn (a, b) { const x = ((a) + (b));\n(console).log((x));\nreturn (x);\n }"
- (emit '(switch a b)) => "switch (a) { default: (b) }"
- (emit '(switch 3
- (+ 1 2) :foo
- 5)) => "switch (3) { case ((1) + (2)): \n 'foo'; \nbreak;\n default: (5) }"
- )
- )
- )
Add Comment
Please, Sign In to add comment