about summary refs log tree commit diff
path: root/universe/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'universe/lisp')
-rw-r--r--universe/lisp/f/README.md5
-rw-r--r--universe/lisp/f/default.nix15
-rw-r--r--universe/lisp/f/main.lisp48
-rw-r--r--universe/lisp/prelude.lisp14
-rw-r--r--universe/lisp/prelude.nix8
5 files changed, 90 insertions, 0 deletions
diff --git a/universe/lisp/f/README.md b/universe/lisp/f/README.md
new file mode 100644
index 000000000000..34e07180d492
--- /dev/null
+++ b/universe/lisp/f/README.md
@@ -0,0 +1,5 @@
+# f.lisp
+
+In this project, I'm attempting to port the Elisp library [`f.el`][1] to Common Lisp.
+
+[1]: https://github.com/rejeep/f.el
diff --git a/universe/lisp/f/default.nix b/universe/lisp/f/default.nix
new file mode 100644
index 000000000000..6911b2102634
--- /dev/null
+++ b/universe/lisp/f/default.nix
@@ -0,0 +1,15 @@
+{
+  depot ? import <depot> {},
+  universe ? import <universe> {},
+  ...
+}:
+
+depot.nix.buildLisp.library {
+  name = "f";
+  deps = with universe.lisp; [
+    prelude
+  ];
+  srcs = [
+    ./main.lisp
+  ];
+}
diff --git a/universe/lisp/f/main.lisp b/universe/lisp/f/main.lisp
new file mode 100644
index 000000000000..a51c38127815
--- /dev/null
+++ b/universe/lisp/f/main.lisp
@@ -0,0 +1,48 @@
+(in-package #:cl-user)
+(defpackage #:main
+  (:documentation "Modern API for working with files and directories.")
+  (:use #:cl)
+  (:shadow #:type))
+(in-package #:main)
+
+;; Common Lisp distinguishes between `namestrings` and `pathnames` as two types
+;; of filename representations.
+;;
+;; A `pathname` is a structured representation of the name of a file, which
+;; consists of six parts:
+;; 1. host
+;; 2. device
+;; 3. directory
+;; 4. name
+;; 5. type
+;; 6. version
+
+;; TODO: Should I be using `string` as a type or `namestring`?
+
+(defmacro type (name in out)
+  `(declaim (ftype (function ,in ,out) ,name)))
+
+(type join (&rest namestring) pathname)
+(defun join (&rest args)
+  "Join ARGS to a single path."
+  (apply #'merge-pathnames args))
+
+(type ext (pathname) string)
+(defun ext (path)
+  "Return the file extension of PATH."
+  (pathname-type path))
+
+;; TODO: Define these tests elsewhere.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Tests
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; join
+(string= (join "path") "path")
+(string= (join "path" "to") "path/to")
+(string= (join "/" "path" "to" "heaven") "/path/to/heaven")
+
+;; ext
+(string= (ext #p"path/to/file.ext") "ext")
+(string= (ext #p"path/to/directory") nil)
diff --git a/universe/lisp/prelude.lisp b/universe/lisp/prelude.lisp
new file mode 100644
index 000000000000..3522567ea0f7
--- /dev/null
+++ b/universe/lisp/prelude.lisp
@@ -0,0 +1,14 @@
+(in-package #:cl-user)
+(defpackage #:prelude
+  (:documentation "Supporting miscellaneous utility functions and macros.")
+  (:use #:cl)
+  (:shadow #:type)
+  (:export #:type #:comment))
+(in-package #:prelude)
+
+;; TODO: Add documentation to these macros.
+
+(defmacro type (name in out)
+  `(declaim (ftype (function ,in ,out) ,name)))
+
+(defmacro comment (&rest _forms) nil)
diff --git a/universe/lisp/prelude.nix b/universe/lisp/prelude.nix
new file mode 100644
index 000000000000..9051f82394ff
--- /dev/null
+++ b/universe/lisp/prelude.nix
@@ -0,0 +1,8 @@
+{ depot ? import <depot> {}, ... }:
+
+depot.nix.buildLisp.library {
+  name = "prelude";
+  srcs = [
+    ./prelude.lisp
+  ];
+}