From 9c9004b2340ac68a450cf2095e8413f0b2c1dbab Mon Sep 17 00:00:00 2001 From: Macoy Madson Date: Sat, 31 Dec 2022 16:00:53 -0500 Subject: [PATCH] Make get-or-create-comptime-var take environment This fixes issues where it is hacky to use from within a defun-comptime, for example, where environment is not an implicit argument. --- doc/Cakelisp.org | 4 ++-- doc/Tutorial_Basics.org | 16 ++++++++-------- runtime/CHelpers.cake | 16 ++++++++++------ runtime/ComptimeHelpers.cake | 8 ++++---- runtime/HotReloadingCodeModifier.cake | 5 +++-- test/CodeModification.cake | 8 ++++---- test/Tutorial_Basics.cake | 6 +++--- 7 files changed, 34 insertions(+), 29 deletions(-) diff --git a/doc/Cakelisp.org b/doc/Cakelisp.org index f036dde..c0bd748 100644 --- a/doc/Cakelisp.org +++ b/doc/Cakelisp.org @@ -281,7 +281,7 @@ There are four major types of compile-time code execution: ** Destructuring signatures Macros and generators use a special syntax for their signatures. For example: #+BEGIN_SRC lisp - (defmacro get-or-create-comptime-var (bound-var-name (ref symbol) var-type (ref any) + (defmacro get-or-create-comptime-var (environment-access any bound-var-name (ref symbol) var-type (ref any) &optional initializer-index (index any)) (return true)) #+END_SRC @@ -312,7 +312,7 @@ Note that you have unlimited control over how you process the provided tokens ar Here's an invocation of that macro: #+BEGIN_SRC lisp -(get-or-create-comptime-var modified-vars bool false) +(get-or-create-comptime-var environment modified-vars bool false) #+END_SRC The binding would result like so: diff --git a/doc/Tutorial_Basics.org b/doc/Tutorial_Basics.org index 4449677..af9c179 100644 --- a/doc/Tutorial_Basics.org +++ b/doc/Tutorial_Basics.org @@ -291,8 +291,8 @@ This allows you to move things around as you like without having to update all t Next, let's invoke the variable creation macro. You can look at its signature to see what you need to provide: #+BEGIN_SRC lisp - (defmacro get-or-create-comptime-var (bound-var-name (ref symbol) var-type (ref any) - &optional initializer-index (index any)) + (defmacro get-or-create-comptime-var (environment-access any bound-var-name (ref symbol) var-type (ref any) + &optional initializer-index (index any)) #+END_SRC It looks just like a regular variable declaration, only this one will share the variable's value during the entire compile-time phase. @@ -302,7 +302,7 @@ Let's create our lookup list. We'll use a C++ ~std::vector~, as it is common in #+BEGIN_SRC lisp (defmacro defcommand (command-name symbol arguments array &rest body any) - (get-or-create-comptime-var command-table (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment command-table (template (in std vector) (addr (const Token)))) (call-on-ptr push_back command-table command-name) (tokenize-push output @@ -356,7 +356,7 @@ From our previous note on ~post-references-resolved~ we learned that our hook ca #+BEGIN_SRC lisp (defun-comptime create-command-lookup-table (environment (ref EvaluatorEnvironment) &return bool) - (get-or-create-comptime-var command-table-already-created bool false) + (get-or-create-comptime-var environment command-table-already-created bool false) (when (deref command-table-already-created) (return true)) (set (deref command-table-already-created) true) @@ -371,12 +371,12 @@ Let's get our command table and make a loop to iterate over it, printing each co #+BEGIN_SRC lisp (defun-comptime create-command-lookup-table (environment (ref EvaluatorEnvironment) &return bool) - (get-or-create-comptime-var command-table-already-created bool false) + (get-or-create-comptime-var environment command-table-already-created bool false) (when (deref command-table-already-created) (return true)) (set (deref command-table-already-created) true) - (get-or-create-comptime-var command-table (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment command-table (template (in std vector) (addr (const Token)))) (for-in command-name (addr (const Token)) (deref command-table) (printFormattedToken stderr (deref command-name)) (fprintf stderr "\n")) @@ -440,12 +440,12 @@ Let's output the generated command data to the console to make sure it's good. H #+BEGIN_SRC lisp (defun-comptime create-command-lookup-table (environment (ref EvaluatorEnvironment) &return bool) - (get-or-create-comptime-var command-table-already-created bool false) + (get-or-create-comptime-var environment command-table-already-created bool false) (when (deref command-table-already-created) (return true)) (set (deref command-table-already-created) true) - (get-or-create-comptime-var command-table (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment command-table (template (in std vector) (addr (const Token)))) (var command-data (addr (template (in std vector) Token)) (new (template (in std vector) Token))) (call-on push_back (field environment comptimeTokens) command-data) diff --git a/runtime/CHelpers.cake b/runtime/CHelpers.cake index 3bf02e8..3e2a46c 100644 --- a/runtime/CHelpers.cake +++ b/runtime/CHelpers.cake @@ -36,13 +36,15 @@ ;; A global and module-local variable "defer" (defmacro before-exit (work-body array) - (get-or-create-comptime-var before-exit-work (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment before-exit-work + (template (in std vector) (addr (const Token)))) (call-on push_back (deref before-exit-work) work-body) (return true)) ;; Run the deferred code (defmacro run-before-exit-work () - (get-or-create-comptime-var before-exit-work (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment before-exit-work + (template (in std vector) (addr (const Token)))) ;; TODO: Should we sort it eventually? (for-in start-work-token (addr (const Token)) (deref before-exit-work) (tokenize-push output @@ -470,7 +472,8 @@ (when (= 0 (call-on compare invocation-name "output-aliased-c-function-invocation")) (return true)) - (get-or-create-comptime-var c-function-aliases (template (in std unordered_map) (in std string) (in std string))) + (get-or-create-comptime-var environment c-function-aliases + (template (in std unordered_map) (in std string) (in std string))) (def-type-alias FunctionAliasMap (template (in std unordered_map) (in std string) (in std string))) (var alias-func-pair (in FunctionAliasMap iterator) @@ -517,7 +520,8 @@ ;; alias, we can set the generators table to it (output-aliased-c-function-invocation) - (get-or-create-comptime-var c-function-aliases (template (in std unordered_map) (in std string) (in std string))) + (get-or-create-comptime-var environment c-function-aliases + (template (in std unordered_map) (in std string) (in std string))) (set (at (field alias contents) (deref c-function-aliases)) (field underlying-func-name contents)) ;; (Logf "aliasing %s to %s\n" (call-on c_str (field underlying-func-name contents)) @@ -603,7 +607,7 @@ (when (and arguments (= 0 (call-on compare (path arguments > contents) "for-dependencies"))) (return true)) - (get-or-create-comptime-var c-forward-macro-functions + (get-or-create-comptime-var environment c-forward-macro-functions (template (in std unordered_map) (in std string) (in std string))) ;; We spoofed the macro call, now we need to rename the function (var function-to-call Token (at (+ 1 startTokenIndex) tokens)) @@ -632,7 +636,7 @@ tokens (ref (const (template (in std vector) Token))) startTokenIndex int output (ref (template (in std vector) Token)) &return bool)) - (get-or-create-comptime-var c-forward-macro-functions + (get-or-create-comptime-var environment c-forward-macro-functions (template (in std unordered_map) (in std string) (in std string))) (set (at (path macro-name > contents) (deref c-forward-macro-functions)) (path function-to-call > contents)) diff --git a/runtime/ComptimeHelpers.cake b/runtime/ComptimeHelpers.cake index 3841495..c6f704c 100644 --- a/runtime/ComptimeHelpers.cake +++ b/runtime/ComptimeHelpers.cake @@ -3,8 +3,8 @@ ;; Binds the variable's address to the named var ;; Note that this causes the caller's function to return false if the binding failed ;; TODO: This is madness, or close to it. All this for every comptime variable reference... -(defmacro get-or-create-comptime-var (bound-var-name (ref symbol) var-type (ref any) - &optional initializer-index (index any)) +(defmacro get-or-create-comptime-var (environment-access any bound-var-name (ref symbol) + var-type (ref any) &optional initializer-index (index any)) (unless (field environment moduleManager) (return false)) @@ -127,13 +127,13 @@ (tokenize-push output (var (token-splice-addr bound-var-name) (addr (token-splice-addr var-type)) null) (scope - (unless (GetCompileTimeVariable environment + (unless (GetCompileTimeVariable (token-splice environment-access) (token-splice-addr var-name) (token-splice-addr var-type-str) (type-cast (addr (token-splice-addr bound-var-name)) (addr (addr void)))) (set (token-splice-addr bound-var-name) (new (token-splice-addr var-type))) (token-splice-array initializer) (var destroy-func-name (addr (const char)) (token-splice-addr destroy-var-func-name-str)) - (unless (CreateCompileTimeVariable environment + (unless (CreateCompileTimeVariable (token-splice environment-access) (token-splice-addr var-name) (token-splice-addr var-type-str) (type-cast (token-splice-addr bound-var-name) (addr void)) destroy-func-name) diff --git a/runtime/HotReloadingCodeModifier.cake b/runtime/HotReloadingCodeModifier.cake index df14b02..37de8ff 100644 --- a/runtime/HotReloadingCodeModifier.cake +++ b/runtime/HotReloadingCodeModifier.cake @@ -63,7 +63,7 @@ &return bool) (var verbose bool false) - (get-or-create-comptime-var modified-vars bool false) + (get-or-create-comptime-var environment modified-vars bool false) (when (deref modified-vars) ;; Modify variables only once (return true)) (set (deref modified-vars) true) @@ -71,7 +71,8 @@ (fprintf stderr "HotReloading: Modifying code for hot-reloading.\n") (fprintf stderr "Subsequent modifications will not be hot-reloading safe\n") - (get-or-create-comptime-var modules-with-import (template (in std unordered_map) (in std string) int)) + (get-or-create-comptime-var environment modules-with-import + (template (in std unordered_map) (in std string) int)) (defstruct modify-definition name (in std string) diff --git a/test/CodeModification.cake b/test/CodeModification.cake index 307c89a..5660930 100644 --- a/test/CodeModification.cake +++ b/test/CodeModification.cake @@ -35,15 +35,15 @@ ;; (return 42)) (defmacro magic-number () - (get-or-create-comptime-var test-var std::string) - (get-or-create-comptime-var test-crazy-var (addr (const (addr (template (in std vector) int))))) + (get-or-create-comptime-var environment test-var std::string) + (get-or-create-comptime-var environment test-crazy-var (addr (const (addr (template (in std vector) int))))) (set (deref test-var) "Yeah") (tokenize-push output (fprintf stderr "The magic number is 42\n")) (return true)) (defun-comptime sabotage-main-printfs (environment (ref EvaluatorEnvironment) &return bool) - (get-or-create-comptime-var test-var std::string) + (get-or-create-comptime-var environment test-var std::string) (fprintf stderr "%s is the message\n" (call-on-ptr c_str test-var)) (var old-definition-tags (template (in std vector) std::string)) ;; Scope to ensure that definition-it and definition are not referred to after @@ -114,7 +114,7 @@ ;; (rename-builtin "var" "badvar") ;; (defmacro var () ;; ;; Var cannot be used within var, because it's undefined. This excludes a lot of macros -;; ;; (get-or-create-comptime-var var-replacements (template (in std vector) (addr (const Token)))) +;; ;; (get-or-create-comptime-var environment var-replacements (template (in std vector) (addr (const Token)))) ;; ;; (for-in replaced-token (addr (const Token)) (addr var-replacements) ;; ;; (NoteAtToken (deref replaced-token) "Replaced already")) diff --git a/test/Tutorial_Basics.cake b/test/Tutorial_Basics.cake index 2947068..eb413fe 100644 --- a/test/Tutorial_Basics.cake +++ b/test/Tutorial_Basics.cake @@ -10,7 +10,7 @@ (defmacro defcommand (command-name symbol arguments array &rest body any) - (get-or-create-comptime-var command-table (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment command-table (template (in std vector) (addr (const Token)))) (call-on-ptr push_back command-table command-name) (tokenize-push output @@ -22,12 +22,12 @@ (fprintf stderr "your name.\n")) (defun-comptime create-command-lookup-table (environment (ref EvaluatorEnvironment) &return bool) - (get-or-create-comptime-var command-table-already-created bool false) + (get-or-create-comptime-var environment command-table-already-created bool false) (when (deref command-table-already-created) (return true)) (set (deref command-table-already-created) true) - (get-or-create-comptime-var command-table (template (in std vector) (addr (const Token)))) + (get-or-create-comptime-var environment command-table (template (in std vector) (addr (const Token)))) (var command-data (addr (template std::vector Token)) (new (template std::vector Token))) (call-on push_back (field environment comptimeTokens) command-data)