1 (defpackage org.lispbuilds.nix
/nix
2 (:documentation
"Utilities for generating Nix code")
6 (:import-from
:arrow-macros
:-
>>)
7 (:import-from
:org.lispbuilds.nix
/util
:replace-regexes
)
15 (in-package org.lispbuilds.nix
/nix
)
17 ;; Path names are alphanumeric and can include the symbols +-._?= and
18 ;; must not begin with a period.
19 (defun make-pname (string)
20 (replace-regexes '("^[.]" "[^a-zA-Z0-9+-._?=]")
24 (defun system-master (system)
25 (first (str:split
"/" system
)))
32 (:string
(nix-string (cadr exp
)))
33 (:list
(apply #'nix-list
(rest exp
)))
34 (:funcall
(apply #'nix-funcall
(rest exp
)))
35 (:attrs
(nix-attrs (cdr exp
)))
36 (:merge
(apply #'nix-merge
(cdr exp
)))
37 (:symbol
(nix-symbol (cadr exp
)))))
39 (defun nix-string (object)
40 (format nil
"\"~a\"" object
))
42 (defun nixify-symbol (string)
43 (flet ((fix-special-chars (str)
44 (replace-regexes '("[_]" "[+]$" "[+][/]" "[+]" "[.]" "[/]")
45 '("__" "_plus" "_plus/" "_plus_" "_dot_" "_slash_")
47 (if (ppcre:scan
"^[0-9]" string
)
48 (str:concat
"_" (fix-special-chars string
))
49 (fix-special-chars string
))))
52 (defun nix-symbol (object)
53 (nixify-symbol (format nil
"~a" object
)))
55 (defun nix-list (&rest things
)
56 (format nil
"[ ~{~A~^ ~} ]" (mapcar 'nix-eval things
)))
57 (defvar *nix-attrs-depth
* 0)
59 (defun nix-attrs (keyvals)
61 (return-from nix-attrs
"{}"))
62 (let ((*nix-attrs-depth
* (1+ *nix-attrs-depth
*)))
65 (->> "{~%*depth*~{~{~A = ~A;~}~^~%*depth*~}~%*depth-1*}"
66 (str:replace-all
"*depth*" (str:repeat
*nix-attrs-depth
* " "))
67 (str:replace-all
"*depth-1*" (str:repeat
(1- *nix-attrs-depth
*) " ")))
68 (mapcar (lambda (keyval)
69 (let ((key (car keyval
))
71 (list (nix-symbol key
)
75 (defun nix-funcall (fun &rest args
)
76 (format nil
"(~a ~{~a~^ ~})"
78 (mapcar 'nix-eval args
)))
80 (defun nix-merge (a b
)
81 (format nil
"(~a // ~b)"