Closed Mercerenies closed 2 years ago
This issue concerned a lack of ability to distinguish between which file we wanted to load and which loading mechanism we wanted to use. The existing this-file
, this-filename
, this-true-filename
mechanisms all determine the filename at evaluation time, in the current file and context.
deflazy
necessitated the need to determine the filename from one context (i.e. the context where define-symbol-macro
was defined) and to determine the loading mechanism from another context (i.e. are we calling the symbol macro from a macro expansion or from the standard Godot runtime). The contextual-load
macro decouples this mechanism. It is a macro which takes a literal string as argument and conditionally transforms it. We evaluate this-true-filename
in the symbol macro and then return an S-expression containing the result of that passed to the name contextual-load
. The contextual-load
gets evaluated in the calling context, allowing us to conditionally resolve the preload to a virtual macro name if necessary.
The underlying mechanism for contextual-load
is the special form sys/contextual-filename
, which is not exposed as the macro is already deadly enough without exposing the internals directly. We should probably make the system directive a bit safer (currently, it can panic on a bad filename).
As a follow-on to #50, as of bfa7f47c1eb74dde7e4a15f4eee12abeda9d5f59,
deflazy
can be used only during runtime. Specifically, consider the following code.The
deflazy
compiles to a private function and a symbol macro. Thenbar
is literally compiled to(Assuming this code is running in a REPL and
_lazy_0
is the name of the private function in question; these conditions are true in a freshly-opened REPL)This expansion of the symbol macro
foo
works perfectly well at runtime, butbar
is going to be evaluated at compile-time, during the macro expansion phase, and at that time, the nameres://REPL.gd
is certainly no good.