Tech News
← Back to articles

Homegrown Closures for Uxn

read original related products more articles

Homegrown closures for uxn

at least, kind of...

For a week or so now, I've been writing niënor, a "lispy environment for uxn". I did not want it to become a full-blown lisp but just another way of writing uxntal. Uxntal is a bit too dense for my liking, and I prefer lisp/scheme s-expression syntax. Niënor is just a compiler and a macroexpander that takes in scheme-like code and spits out uxn roms.

This article describes my homegrown method of creating lexically scoped closures in this environment.

Lambdas

Or, anonymous functions.

When ignoring lexical scope lambdas are really simple to implement if we can already compile named functions.

Here is some simplified code with commentary from the compiler that does exactly that (I've skipped some boring parts). We simply give the anonymous function a name, skip the compilation for now (add to epilogue), and push the name (that will get resolved later by the compiler) in its place.

exp ) (tuple-case (list->tuple ;; [...] ; if it's a lambda ((_λ args body) ( let ((used-locals ; check what symbols the lambda uses, ((used-locals ; intersect them with the list of known locals (function arguments, local values declared in let expressions) (intersect ; to get a list of used locals (get env 'locals #n) (code->used-symbols body)))) ( if ( null? used-locals) ; if there are no locals, used-locals) ( let ((name (gensym))) ; generate a random name for that function ((name (gensym))) ;; [...] ; <- put this function into the epilogue, so it gets compiled at the end of the program (put env 'epilogue ( append (get env 'epilogue #n) (get env 'epilogue #n) `((_defun ,name ,args ,body)))) ;; [...] ;; in this place, the gensymmed name gets pushed, and later resolved to the functions' location ;; so an expression like ;; (let ((f (λ (x) (+ x 1)))) ;; ...) ;; would resolve to ;; (let ((f @@gensym__1)) ;; ...) ;; @@gensym__1 being the generated name of the now de-anonymized function :P )))))

Closures

... continue reading