Mercerenies / gdlisp

Lisp on the Godot platform
GNU General Public License v3.0
141 stars 1 forks source link

`macrolet` attempted recursion #23

Closed Mercerenies closed 3 years ago

Mercerenies commented 3 years ago

If we try to use a function whose name matches the name of a macrolet being defined, as follows

(defn foo () ...)
(macrolet ((foo () (foo)))
  (foo))

...we get this message on output

Error: failed to fill whole buffer

and the Godot server dies and doesn't work again for the rest of the life of the process. What even.

Mercerenies commented 3 years ago

Also worth noting that, once we fix this, we need to make sure the scoping issues are right if we do multiple macrolet in parallel and they reference outer functions with the same name as the macros.

Mercerenies commented 3 years ago

This may just be the tip of the iceberg. Both of the following snippets run successfully and produce (incorrect) code, when both should be a name error at compile time.

(macrolet ((foo () (foo)))
  ())

 

(defmacro foo ()
  (foo))
Mercerenies commented 3 years ago

ea7b45d fixes this for the non-macrolet cases.

Mercerenies commented 3 years ago

Resolved as of 7986d69.

macrolet now correctly binds all of the names internally. If a macrolet macro attempts to reference its own name, it will end up looking in the enclosing scope (which is not necessarily an error). If the name doesn't exist in the outer scope, it's an error.