________________ MACROS AND RPN lro ________________ <2019-01-13 Sun> Table of Contents _________________ macros macros ====== I would like to change /rpn-func/ to a macro that just returned the /lambda/ needed to be in the `init-dict'. So it would need to take the function, and how many args it needs. It would expand from this: ,---- | (rpn-func + 2) `---- To this: ,---- | (lambda (stack dict) | (let*-values (((var1 stack) (pop stack)) | ((var2 stack) (pop stack))) | (push (+ var2 var1) stack))) `---- Which shouldn't be too difficult. ,---- | (define-syntax rpn-func | (syntax-rules () | ((rpn-func func 2) | (lambda (stack dict) | (let*-values (((var1 stack) (pop stack)) | ((var2 stack) (pop stack))) | (push (func var2 var1) stack)))) | | ((rpn-func func 1) | (lambda (stack dict) | (let*-values (((var stack) (pop stack))) | (push (func var) stack)))))) `---- And that cleans up the `init-dict' nicely. I would also like to have a go at using a macro to generate some of the `init-dict', probably not going to keep it in the code, but something to try. I would have to feed it a list of lists, each inner list having three members, the function name to use on the commandline, the scheme function name, and the number of arguents it takes. Of course this will only work if we only generate the function that use scheme functions directly, so no $ or D or anything. ,---- | (define-syntax generate-init-dict | (syntax-rules () | ((generate-init-dict () form . forms) | (list form . forms)) | | ((generate-init-dict ((name func args)) form . forms ) | (generate-init-dict () (cons (quote name) (rpn-func func args)) form . forms)) | | ((generate-init-dict ((name func args) . variables) form . forms ) | (generate-init-dict variables (cons (quote name) (rpn-func func args)) form . forms)) | | ((generate-init-dict ((name func args) . variables)) | (generate-init-dict variables (cons (quote name) (rpn-func func args)))) | )) `---- Now if we wanted to generate the `init-dict' all we would have to do is: ,---- | (define init-dict (generate-init-dict ((+ + 2) (- - 2) (* * 2)))) | ;;etc for the rest of the scheme funcs `---- I could write things like /D/ and /if/ as functions outside of the /init-dict/, then add another clause to the macro so that functions without args are just put straight into the cons without the /rpn-func/. ,---- | (define-syntax generate-init-dict | (syntax-rules () | ((generate-init-dict () form . forms) | (list form . forms)) | | ((generate-init-dict ((name func args)) form . forms ) | (generate-init-dict () (cons (quote name) (rpn-func func args)) form . forms)) | | ((generate-init-dict ((name func)) form . forms ) | (generate-init-dict () (cons (quote name) func) form . forms)) | | ((generate-init-dict ((name func args) . variables) form . forms ) | (generate-init-dict variables (cons (quote name) (rpn-func func args)) form . forms)) | | ((generate-init-dict ((name func) . variables) form . forms ) | (generate-init-dict variables (cons (quote name) func) form . forms)) | | ((generate-init-dict ((name func args) . variables)) | (generate-init-dict variables (cons (quote name) (rpn-func func args)))) | | ((generate-init-dict ((name func) . variables)) | (generate-init-dict variables (cons (quote name) func))) | )) `---- Dang I might actually use this now. It would be way easier for people to add their own functions in the code. Just implement the scheme function that takes the dict and the stack and returns the stack, put the name you want it to use and the name of the func in the `init-dict' generation. And away you go.