Arc Forumnew | comments | leaders | submitlogin
2 points by aw 2100 days ago | link | parent

> allowing local variables to override macros

Yes, that's easy to do. At the top of ac-call in ac.scm where it checks ac-macro?, also check to see that "fn" isn't a symbol and in env.



3 points by waterhouse 2100 days ago | link

Yup, I have that change.

(define (ac-call fn args env) (let ((macfn (ac-macro? fn))) - (cond (macfn + (cond ((and macfn (not (lex? fn env))) (ac-mac-call macfn args env))

Now, if you wanted to define the macro locally, like this...

  (let-macro my-def (name args . body) `(= ,name (fn ,args ,@body))
    ... (my-def ...))
Then, well, you could conceivably change the semantics of "env" as it's passed around in ac.scm. Currently it's just a list of variables that are bound, and things test for whether a variable is present in that list. You could change it to a list of (variable-name macro-it's-bound-to-if-any), and have the special form (let-macro name arglist bodexpr . body) insert `(,name (fn ,arglist ,bodexpr) into env, while everything else puts in (variable nil), and change all the existing tests on "env" to search for "a list whose car is x" rather than "x", and lastly make ac-call call the macro-function on the expression if it finds one in the lexenv.

In theory, one could put arbitrarily complicated information, such as about deduced types of variables, into this "env" mapping, and implement some amount of compiler optimization that way.

First-class macros, of course, are the semantically nicest approach, but more difficult to compile.

-----

3 points by waterhouse 2099 days ago | link

Gack, formatting got messed up on the first snippet. Too late to edit. Should be:

   (define (ac-call fn args env)
     (let ((macfn (ac-macro? fn)))
  -    (cond (macfn
  +    (cond ((and macfn (not (lex? fn env)))
              (ac-mac-call macfn args env))

-----