Browse Source

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.
master
Macoy Madson 9 months ago
parent
commit
9c9004b234
  1. 4
      doc/Cakelisp.org
  2. 16
      doc/Tutorial_Basics.org
  3. 16
      runtime/CHelpers.cake
  4. 8
      runtime/ComptimeHelpers.cake
  5. 5
      runtime/HotReloadingCodeModifier.cake
  6. 8
      test/CodeModification.cake
  7. 6
      test/Tutorial_Basics.cake

4
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:

16
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)

16
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))

8
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)

5
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)

8
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"))

6
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)

Loading…
Cancel
Save