Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
3.4 KiB

4 years ago
  1. ;;; parseclj.el --- Clojure/EDN parser -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2017-2018 Arne Brasseur
  3. ;; Author: Arne Brasseur <arne@arnebrasseur.net>
  4. ;; Keywords: lisp clojure edn parser
  5. ;; Package-Requires: ((emacs "25") (a "0.1.0alpha4"))
  6. ;; Version: 0.1.0
  7. ;; This file is not part of GNU Emacs.
  8. ;; This file is free software; you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 3, or (at your option)
  11. ;; any later version.
  12. ;; This file is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;; GNU General Public License for more details.
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU Emacs; see the file COPYING. If not, write to
  18. ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. ;; Boston, MA 02110-1301, USA.
  20. ;;; Commentary:
  21. ;; Top level API for the Clojure parser.
  22. ;;; Code:
  23. (require 'parseclj-parser)
  24. (require 'parseclj-ast)
  25. (defun parseclj-parse-clojure (&rest string-and-options)
  26. "Parse Clojure source to AST.
  27. Reads either from the current buffer, starting from point, until
  28. `point-max', or reads from the optional string argument.
  29. STRING-AND-OPTIONS can be an optional string, followed by
  30. key-value pairs to specify parsing options.
  31. - `:lexical-preservation' Retain whitespace, comments, and
  32. discards. Defaults to nil.
  33. - `:fail-fast' Raise an error when encountering invalid syntax.
  34. Defaults to t.
  35. - `:read-one'
  36. Read a single form. Defaults to false: parse the complete input."
  37. (if (stringp (car string-and-options))
  38. (with-temp-buffer
  39. (insert (car string-and-options))
  40. (goto-char 1)
  41. (apply 'parseclj-parse-clojure (cdr string-and-options)))
  42. (let* ((value-p (lambda (e)
  43. (and (parseclj-ast-node-p e)
  44. (not (member (parseclj-ast-node-type e) '(:whitespace :comment :discard))))))
  45. (options (apply 'a-list :value-p value-p string-and-options))
  46. (lexical? (a-get options :lexical-preservation)))
  47. (parseclj-parser (if lexical?
  48. #'parseclj-ast--reduce-leaf-with-lexical-preservation
  49. #'parseclj-ast--reduce-leaf)
  50. (if lexical?
  51. #'parseclj-ast--reduce-branch-with-lexical-preservation
  52. #'parseclj-ast--reduce-branch)
  53. options))))
  54. (defun parseclj-unparse-clojure (ast)
  55. "Parse Clojure AST to source code.
  56. Given an abstract syntax tree AST (as returned by
  57. `parseclj-parse-clojure'), turn it back into source code, and
  58. insert it into the current buffer."
  59. (if (parseclj-ast-leaf-node-p ast)
  60. (insert (a-get ast :form))
  61. (if (eql (parseclj-ast-node-type ast) :tag)
  62. (parseclj-ast--unparse-tag ast)
  63. (parseclj-ast--unparse-collection ast))))
  64. (defun parseclj-unparse-clojure-to-string (ast)
  65. "Parse Clojure AST to a source code string.
  66. Given an abstract syntax tree AST (as returned by
  67. `parseclj-parse-clojure'), turn it back into source code, and
  68. return it as a string"
  69. (with-temp-buffer
  70. (parseclj-unparse-clojure ast)
  71. (buffer-substring-no-properties (point-min) (point-max))))
  72. (provide 'parseclj)
  73. ;;; parseclj.el ends here