changelog shortlog graph tags branches changeset file revisions annotate raw help

Mercurial > demo / tk.lisp

revision 10: 79737134254d
parent 8: bebb76da449c
child 13: 1fedeaa5bfc5
     1.1--- a/tk.lisp	Mon May 08 21:11:03 2023 -0400
     1.2+++ b/tk.lisp	Fri May 12 22:58:05 2023 -0400
     1.3@@ -1,31 +1,15 @@
     1.4-(in-package #:demo)
     1.5+(in-package :demo)
     1.6 
     1.7-(defvar *cargo-target* #P"/Users/ellis/dev/otom8/demo/target/")
     1.8+(defvar *cargo-target* #p"/Users/ellis/dev/otom8/demo/target/")
     1.9 
    1.10 (defvar *rs-macros* nil)
    1.11 
    1.12-(defmacro rs-find-dll (name &optional debug)
    1.13-  "Find the rust dll specified by NAME."
    1.14-  (cond
    1.15-    ((uiop:directory-exists-p (merge-pathnames *cargo-target* "release"))
    1.16-     `,(mkstr "./target/release/" name))
    1.17-    ((uiop:directory-exists-p  (merge-pathnames *cargo-target* "debug"))
    1.18-     `,(mkstr "./target/debug/" name))
    1.19-    (t (progn
    1.20-	 (uiop:run-program `("cargo" "build" ,(unless debug "--release")) :output t)
    1.21-	 `,(find-rust-dll name debug)))))
    1.22+(defun mkstr (&rest args)
    1.23+  (with-output-to-string (s)
    1.24+    (dolist (a args) (princ a s))))
    1.25 
    1.26-(defmacro rs-defmacro (args &body body)
    1.27-  "Define a macro which expands to a string of Rust code.")
    1.28-
    1.29-(defun rs-macroexpand-1 (form &optional env))
    1.30-
    1.31-(defun rs-macroexpand (env &rest body)
    1.32-  "Cbindgen is quite the menace and really doesn't like our macros used
    1.33-to generate C FFI bindings. To compensate for this, we use a tool
    1.34-called cargo-expand by the most excellent dtolnay which expands Rust
    1.35-macros. The expansions are assembled into an equivalent Rust source
    1.36-file which cbindgen won't get stuck in an infinite compile loop on.")
    1.37+(defun symb (&rest args)
    1.38+  (values (intern (apply #'mkstr args))))
    1.39 
    1.40 (defun random-id ()
    1.41   (format NIL "~8,'0x-~8,'0x" (random #xFFFFFFFF) (get-universal-time)))
    1.42@@ -34,13 +18,6 @@
    1.43   (dolist (path (directory (merge-pathnames (merge-pathnames filename "**/") dir)))
    1.44     (funcall callback path)))
    1.45 
    1.46-(defun mkstr (&rest args)
    1.47-  (with-output-to-string (s)
    1.48-    (dolist (a args) (princ a s))))
    1.49-
    1.50-(defun symb (&rest args)
    1.51-  (values (intern (apply #'mkstr args))))
    1.52-
    1.53 (defun sbq-reader (stream sub-char numarg)
    1.54   "The anaphoric sharp-backquote reader: #`((,a1))"
    1.55   (declare (ignore sub-char))
    1.56@@ -53,3 +30,80 @@
    1.57 (eval-when (:execute)
    1.58   (set-dispatch-macro-character
    1.59    #\# #\` #'demo:sbq-reader))
    1.60+
    1.61+;;; RUST MACROS
    1.62+(defmacro rs-find-dll (name &optional debug)
    1.63+  "Find the rust dll specified by NAME."
    1.64+  (cond
    1.65+    ((uiop:directory-exists-p (merge-pathnames *cargo-target* "release"))
    1.66+     `,(mkstr "./target/release/" name))
    1.67+    ((uiop:directory-exists-p  (merge-pathnames *cargo-target* "debug"))
    1.68+     `,(mkstr "./target/debug/" name))
    1.69+    (t `(progn
    1.70+	 ,(uiop:run-program '("cargo" "build" (unless debug "--release")) :output t)
    1.71+	 (rs-find-dll ,name ,debug)))))
    1.72+
    1.73+(defun rs-mod-form (crate &optional mods pub)
    1.74+  "Generate a basic mod form (CRATE . [MODS] [PUB])"
    1.75+    `(,crate ,mods ,pub))
    1.76+
    1.77+(defmacro with-rs-env (imports &body body)
    1.78+  "Generate an environment for use within a Rust generator macro."
    1.79+  `(let ((imports ,(mapcar #'rs-mod-form imports)))
    1.80+     (format nil "~A~&~A" imports ',body)))
    1.81+
    1.82+(defun rs-use (crate &optional mods pub)
    1.83+  "Generate a single Rust use statement."
    1.84+  (concatenate
    1.85+   'string
    1.86+   (if pub "pub " "")
    1.87+   "use " crate "::{"
    1.88+   (cond
    1.89+     ((consp mods)
    1.90+      (reduce
    1.91+       (lambda (x y) (format nil "~A,~A" x y))
    1.92+       mods))
    1.93+     (t mods))
    1.94+   "};"))
    1.95+
    1.96+(defun rs-mod (mod &optional pub)
    1.97+  "Generate a single Rust mod statement."
    1.98+  (concatenate
    1.99+   'string
   1.100+   (if pub "pub " "")
   1.101+   "mod " mod ";"))
   1.102+
   1.103+(defun rs-imports (&rest imports)
   1.104+  "Generate a string of Rust 'use' statements."
   1.105+  (cond
   1.106+    ((consp imports)
   1.107+     (mapcar (lambda (x) (apply #'rs-use (apply #'rs-mod-form x))) imports))
   1.108+    (t imports)))
   1.109+
   1.110+(defmacro rs-extern-c-fn (name args &optional pub unsafe no-mangle &body body)
   1.111+  "Generate a Rust extern 'C' fn."
   1.112+  `(concatenate
   1.113+   'string
   1.114+   ,(when no-mangle (format nil "#[no_mangle]~&"))
   1.115+   ,(when pub "pub ")
   1.116+   ,(when unsafe "unsafe ")
   1.117+   "extern \"C\" fn " ,name "("
   1.118+   ,(cond
   1.119+      ((consp args) (reduce (lambda (x y) (format nil "~A,~A" x y)) args))
   1.120+      (t args))
   1.121+   ")" "{" ,@body "}"))
   1.122+
   1.123+(defun rs-obj-impl (obj)
   1.124+  "Implement Objective for give OBJ."
   1.125+  (format nil "impl Objective for ~A {};" obj))
   1.126+
   1.127+;; (defun rs-macroexpand-1 (form &optional env))
   1.128+
   1.129+;; (defun rs-macroexpand (env &rest body)
   1.130+;;   "Cbindgen is quite the menace and really doesn't like our macros used
   1.131+;; to generate C FFI bindings. To compensate for this, we use a tool
   1.132+;; called cargo-expand by the most excellent dtolnay which expands Rust
   1.133+;; macros. The expansions are assembled into an equivalent Rust source
   1.134+;; file which cbindgen won't get stuck in an infinite compile loop on.")
   1.135+
   1.136+;;;