justinethier / cyclone

:cyclone: A brand-new compiler that allows practical application development using R7RS Scheme. We provide modern features and a stable system capable of generating fast native binaries.
http://justinethier.github.io/cyclone/
MIT License
823 stars 42 forks source link

No defmacro support #480

Closed BracketMaster closed 3 years ago

BracketMaster commented 3 years ago

Sometimes I like to write quick and dirty macros, but it seems cyclone doesn't support this? It seems SCM will allow you to make macros hygenic with gentemp for example. Is this available in cyclone?

justinethier commented 3 years ago

There is no defmacro but you can use explicit renaming macros if you want something quick and dirty, EG:

    (define-syntax when
      (er-macro-transformer
        (lambda (exp rename compare)
          (if (null? (cdr exp)) (error/loc "empty when" exp))
          (if (null? (cddr exp)) (error/loc "no when body" exp))
          `(if ,(cadr exp)
               ((lambda () ,@(cddr exp)))))))
BracketMaster commented 3 years ago

Thanks. I also wonder if there's a way to "preview" the results of a macro expansion before things get evaluated. This would help with debugging.

justinethier commented 3 years ago

There are a few ways to do that:

BracketMaster commented 3 years ago

it seems expand has three arguments, what is the third for? https://justinethier.github.io/cyclone/docs/api/scheme/cyclone/macros#macroexpand

BracketMaster commented 3 years ago

It also seems er-macro-transformer is implicitly defined within define-syntax. https://github.com/justinethier/cyclone/blob/7f4f67f612bcccd2d13a75cbe1e3f282e649a26b/scheme/eval.sld#L533

justinethier commented 3 years ago

it seems expand has three arguments, what is the third for? https://justinethier.github.io/cyclone/docs/api/scheme/cyclone/macros#macroexpand

Good question. The third argument is an environment of variables renamed directly by macros. For simple testing you can just pass '() to indicate an empty environment.

Let me see about putting together some documentation to better explain how to use this function.

justinethier commented 3 years ago

It also seems er-macro-transformer is implicitly defined within define-syntax. https://github.com/justinethier/cyclone/blob/7f4f67f612bcccd2d13a75cbe1e3f282e649a26b/scheme/eval.sld#L533

That is true. Do you have concerns?

BracketMaster commented 3 years ago

Not a problem, just something I observed.

Also, your macro docs are down: https://justinethier.github.io/cyclone/docs/api/scheme/cyclone/macros

Lastly, the following seems to not work:

; myfile.scm
(define-syntax while
  (syntax-rules ()
    ((_ condition . body)
     (let loop ()
       (cond (condition
          (begin . body)
          (loop)))))))

(define x 0)
(expand '(while (< x 3) (set! x (+ x 1)) (display x)) *global-environment* `())

(exit 0)

icyc -s myfile.scm complains Error: Invalid type: expected pair, found : ()

justinethier commented 3 years ago

Thanks for the feedback on this :)

The (scheme cyclone macros) module is no longer used. expand is documented here: http://justinethier.github.io/cyclone/docs/api/scheme/eval#expand

In your example, the macro expansion itself seems fine. The issue is with calling expand. You know, when debugging I generally use the other methods and do not call expand directly. But it would be helpful if we had a way to reliably debug macro expansions from the REPL. Let me take a closer look and see what can be done.

justinethier commented 3 years ago

Apologies, the appropriate call is:

(expand '(while (< x 3) (set! x (+ x 1)) (display x)) *global-environment* (env:extend-environment '() '() '())

That works but is a lot to type and remember... So expand has been updated on master to only require a single expression argument:

(expand '(while (< x 3) (set! x (+ x 1)) (display x)))

This is available now if you are building from source and will be included in the next release.