/load/ppr.arc

http://github.com/alimoeeny/arc · Unknown · 180 lines · 160 code · 20 blank · 0 comment · 0 complexity · 4430c1f943da74492545d30514a88d2b MD5 · raw file

  1. (= pprsyms* (fill-table (table)
  2. '(quote "'"
  3. quasiquote "`"
  4. unquote ","
  5. unquote-splicing ",@")))
  6. (def sp ((o n 1))
  7. " Print a number of spaces. "
  8. (repeat n (pr " ")))
  9. (def print-spaced (xs)
  10. " Print the expressions in the list separated by spaces. "
  11. (when xs
  12. (print car.xs)
  13. (each x cdr.xs (sp) print.x)))
  14. (def print (x)
  15. " Print an expression on one line, replacing quote, unquote,
  16. quasiquote, unquote-splicing, and make-br-fn with their respective symbols. "
  17. (do (aif (or atom.x dotted.x)
  18. write.x
  19. (pprsyms* car.x)
  20. (do pr.it
  21. (print cadr.x))
  22. (is car.x 'make-br-fn)
  23. (do (pr "[") (print-spaced cadr.x) (pr "]"))
  24. (do (pr "(") print-spaced.x (pr ")")))
  25. x))
  26. (= oneline* 45)
  27. (def len (x (o c 0))
  28. " Measures the length of a string, vector, table, list or dotted list. "
  29. (if (isa x 'string) ($.string-length x)
  30. (isa x 'vec) ($.vector-length x)
  31. (isa x 'table) ($.hash-table-count x)
  32. (and atom.x x) (+ c 1)
  33. acons.x (len cdr.x (+ c 1))
  34. c))
  35. (mac indent (col . body)
  36. `(do (unless noindent sp.col)
  37. ,@body))
  38. (mac ppr-sub body
  39. `(indent col
  40. (let whole (tostring print.x)
  41. (if (< len.whole oneline*)
  42. (do pr.whole nil)
  43. (do ,@body t)))))
  44. (def indent-pairs (xs (o col 0))
  45. (let l (apply max 0 (map len:tostring:print:car (keep cdr pair.xs)))
  46. (on x pair.xs
  47. (if (~is index 0)
  48. (do (prn)
  49. (sp col)))
  50. (let str (tostring:print car.x)
  51. (if cdr.x
  52. (do pr.str
  53. (sp:- l len.str -1)
  54. (ppr-main cadr.x (+ col 1 l) t))
  55. ; lone tail expression
  56. (do (sp (+ l 1))
  57. (ppr-main car.x (+ col (+ l 1)) t)))))))
  58. (def indent-block (xs (o col 0))
  59. (each x xs (prn) (ppr-main x col)))
  60. (def indent-mac (xs (o args 0) (o col 0))
  61. (print-spaced (firstn args xs))
  62. (indent-block (nthcdr args xs) (+ col 2)))
  63. (def indent-basic (xs l (o col 0))
  64. (if (all [or atom._ (and (is car._ 'quote) (atom cadr._))]
  65. xs)
  66. print-spaced.xs
  67. (do (ppr-main car.xs (+ col 2 l) t)
  68. (indent-block cdr.xs (+ col 2 l)))))
  69. (def indent-wave (xs (o col 0))
  70. (do (ppr-main car.xs col t)
  71. (on x cdr.xs
  72. (prn)
  73. (ppr-main x (+ col (* 2 (mod (+ index 1) 2)))))))
  74. (= ifline* 20)
  75. (def indent-if (l)
  76. (fn (xs (o col 0))
  77. (if (< len.xs 4)
  78. (on x xs
  79. (if (~is index 0) (prn))
  80. (ppr-main x (+ col 2 l) (is index 0)))
  81. (all [< (len:tostring print._) ifline*]
  82. pair.xs)
  83. (indent-pairs xs (+ col 2 l))
  84. (indent-wave xs (+ col 2 l)))))
  85. (def indent-with (l)
  86. (fn (xs (o col 0))
  87. (pr "(")
  88. (indent-pairs car.xs (+ col 3 l))
  89. (pr ")")
  90. (indent-block cdr.xs (+ col 3))))
  91. (def indent-def (xs (o col 0))
  92. (print-spaced (firstn 2 xs))
  93. (if (isa xs.2 'string)
  94. (do (prn)
  95. (sp (+ col 2))
  96. (pr #\" xs.2 #\")
  97. (indent-block (nthcdr 3 xs) (+ col 2)))
  98. (indent-block (nthcdr 2 xs) (+ col 2))))
  99. (def indent-case (n)
  100. (fn (xs (o col 0))
  101. (print-spaced:firstn n xs)
  102. (prn)
  103. (sp (+ col 2))
  104. (indent-pairs (nthcdr n xs) (+ col 2))))
  105. (= indent-rules*
  106. (fill-table (table)
  107. `(if ,(indent-if 2)
  108. aif ,(indent-if 3)
  109. with ,(indent-with 4)
  110. withs ,(indent-with 5)
  111. def ,indent-def
  112. mac ,indent-def
  113. do ,[indent-basic _ 2 _2]
  114. and ,[indent-basic _ 3 _2]
  115. or ,[indent-basic _ 2 _2]
  116. nor ,[indent-basic _ 3 _2]
  117. case ,(indent-case 1)
  118. caselet ,(indent-case 2)
  119. fn ,[indent-mac _ 1 _2])))
  120. (def ppr-main (x (o col 0) (o noindent nil))
  121. " Recursive main body of the ppr function. "
  122. (aif (or atom.x dotted.x) ;just print the expression if it's an atom or dotted list
  123. (indent col
  124. print.x
  125. nil)
  126. (is car.x 'make-br-fn) ;if the expression is a br-fn, print the brackets and then the contents
  127. (ppr-sub
  128. (pr "[")
  129. (ppr-main cadr.x (+ col 1) t)
  130. (pr "]"))
  131. (pprsyms* car.x)
  132. (ppr-sub
  133. pr.it
  134. (ppr-main cadr.x (+ col len.it) t))
  135. (ppr-sub
  136. (pr "(")
  137. (withs (proc car.x
  138. args sig.proc
  139. n len.args
  140. str (tostring:print proc)
  141. l len.str
  142. xs cdr.x)
  143. (if (isa proc 'cons)
  144. (do (ppr-main proc (+ col 1) t)
  145. (indent-block xs (+ col 1)))
  146. (do pr.str
  147. (when xs
  148. (sp)
  149. (aif indent-rules*.proc
  150. (it xs col)
  151. (and (isa proc 'sym) (bound proc) (isa (eval proc) 'mac))
  152. (if (or dotted.args (and args (~acons args)))
  153. (indent-mac xs (- len.args 1) col)
  154. (indent-mac xs 0 col))
  155. (indent-basic xs l col)))))
  156. (pr ")")))))
  157. (def ppr l
  158. " Pretty print. This function displays arc code with proper
  159. indenting and representation of syntax. "
  160. (each x l (ppr-main x) (prn)))