Guest User

Untitled

a guest
Jan 22nd, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.65 KB | None | 0 0
  1. (defn parse-args
  2. [args]
  3. (string/join ", " (for [arg args]
  4. (cond
  5. (map? arg) (let [{:keys [keys]} arg]
  6. (format "{ %s }" (parse-args keys)))
  7. :else arg))))
  8.  
  9. (defn emit
  10. [x]
  11. (cond
  12. (list? x) (let [[op & args] x]
  13. (cond
  14. ('#{const var let} op) (format "%s %s = %s" op (first args) (emit (second args)))
  15. ('#{=>} op) (format "((%s) %s %s)" (parse-args (first args)) op (emit (second args)))
  16. ('#{function} op) (format "%s %s (%s) { %s }" op (first args)
  17. (parse-args (second args))
  18. (emit (apply list (into '[do] (rest (rest args))))))
  19. ('#{+ - == / ===} op) (format "(%s %s %s)" (emit (first args)) op (emit (second args)))
  20. ('#{new} op) (format "(%s %s(%s))" op (first args) (string/join ", " (map emit (rest args))))
  21. ('#{switch} op) (format "%s %s { %s default: %s }"
  22. op
  23. (emit (first args))
  24. (string/join "\n" (for [[k v] (partition 2 (butlast (rest args)))]
  25. (format "case %s: \n %s; \nbreak;\n" (emit k) (emit v))))
  26. (emit (last args)))
  27. ('#{do} op) (string/join ";\n" (concat (map emit args) [""]))
  28. ('#{return} op) (format "%s %s" op (string/join ", " (map emit args)))
  29. (and (symbol? op)
  30. (string/starts-with? op ".")) (format "%s%s(%s)" (emit (first args)) op (emit (second args)))
  31.  
  32. :else (format "(%s(%s))" op (string/join ", " (map emit args)))
  33. ))
  34. (keyword? x) (format "'%s'" (name x))
  35. (string? x) (format "\"%s\"" x)
  36. (vector? x) (format "([%s])" (string/join ", " (map emit x)))
  37. (map? x) (format "({%s})" (string/join ", " (for [[k v] x] (string/join ": " [(emit k) (emit v)]))))
  38. :else (format "(%s)" x)))
  39.  
  40. (deftest code
  41. (let []
  42. (fact
  43. (emit '0) => "(0)"
  44. (emit '(const x 44)) => "const x = (44)"
  45. (emit '(=> [x] x)) => "((x) => (x))"
  46. (emit '(+ 1 2)) => "((1) + (2))"
  47. (emit '(var myFoo (=> [x y] (+ x y)))) => "var myFoo = ((x, y) => ((x) + (y)))"
  48. (emit '(myFoo 1 2)) => "(myFoo((1), (2)))"
  49. (emit '(function myFn [a b] (return (+ a b)))) => "function myFn (a, b) { return ((a) + (b));\n }"
  50. (emit ':aaa) => "'aaa'"
  51. (emit '(const x (+ :xyz 33))) => "const x = ('xyz' + (33))"
  52. (emit '(const f (=> [{:keys [a]}] (+ a 55)))) => "const f = (({ a }) => ((a) + (55)))"
  53. (emit '(const f (=> [] (+ 55 0)))) => "const f = (() => ((55) + (0)))"
  54. (emit '[]) => "([])"
  55. (emit '[1 :a "b" (f c)]) => "([(1), 'a', \"b\", (f((c)))])"
  56. (emit '{:foo 33}) => "({'foo': (33)})"
  57. (emit '(.get x 33)) => "(x).get((33))"
  58. (emit '(.values Object {:a 33})) => "(Object).values(({'a': (33)}))"
  59. (emit '(do 1 2)) => "(1);\n(2);\n"
  60. (emit '(new Set [1 2])) => "(new Set(([(1), (2)])))"
  61. (emit '(function myFn
  62. [a b]
  63. (const x (+ a b))
  64. (.log console x)
  65. (return x)))
  66. => "function myFn (a, b) { const x = ((a) + (b));\n(console).log((x));\nreturn (x);\n }"
  67. (emit '(switch a b)) => "switch (a) { default: (b) }"
  68. (emit '(switch 3
  69. (+ 1 2) :foo
  70. 5)) => "switch (3) { case ((1) + (2)): \n 'foo'; \nbreak;\n default: (5) }"
  71. )
  72. )
  73. )
Add Comment
Please, Sign In to add comment