Fork me on GitHub
#code-reviews
<
2022-01-12
>
stopa02:01:36

Hey team, I wrote the “simplest Lisp interpreter I could, which supports macros”. Two interesting things in there. I have a scope variable, which when evaluated, returns the current lexical scope:

((fn (x) scope) 1)
> {x 1 ...}
I then represent closures as a literal of the form:
(clo scope args body)
Macros, similarly are a literal of the form:
(mac (clo scope args body))
A macro, stores a closure that runs over unveluated arguments, and then evaluates that: https://github.com/stopachka/simple-lisp/blob/main/src/simple_lisp/core.clj#L50-L54 --- Now, I want to create a fn macro, which generates a closure, with the current lexical environment:
; intended ->
(defmacro fn (args body) `(list 'clo scope '~args '~body)
Buut, I am having a bug. Here’s the failing case: https://github.com/stopachka/simple-lisp/blob/main/src/simple_lisp/core.clj#L108-L112 When the macro “expands”, it seems to lose the lexical scope. So running:
((fn (x)
  ((fn (y) (+ x y)) 2)) 1)]))
Fails, because in the inner function x loses it’s value I know it must be an issue with a macro, because if I write:
'((fn (x)
  ((list 'clo scope '(y) '(+ x y)) 2)) 1)
It works honky dory. I may be missing something simple, but have been hitting my head on this over the day. If ya’ll have thoughts, would love your input on the code! You can play with it using nrepl, by running clj -R:nREPL -m nrepl.cmdline -p 3434 -i