Actually, it would have been nice to have something like

    (prepend-toplevel-form syntax)


Because then you could have done somthing like

(define-syntax rx
     (lambda (x)
          (syntax-case x ()
              ((_ pat)
                (with-syntax (((nm) (generate-temporaries (list #'pat))))
                     (prepend-toplevel-form #'(define nm (make-regexp pat)))

                     #'(let ((val (hash-ref defined 'nm err)))
                             (if (eq? val err)
                                  (let ((val (make-regexp pat)))
                                        (hash-set! defined 'nm val)
                                         val)
                                   val))))))))



On Thu, Feb 11, 2016 at 10:37 AM, Stefan Israelsson Tampe <
stefan.ita...@gmail.com> wrote:

> the result of eval-when will be available only att specified phases. So
> your eval-when code will not be available
> except at expansion. Also it looks like you want to precompile the
> regexes. This is not a stupid idea and should
> be done at load time because regexp literals is not supported by guile
> scheme.
>
> I'm not sure what the best way to implement this is but why not memoize
> the value of the regexp like in
>
> (define err         (cons 'not 'defined)
> (define defined (make-hash-table))
> (define-syntax rx
>      (lambda (x)
>           (syntax-case x ()
>               ((_ pat)
>                 (with-syntax (((nm) (generate-temporaries (list #'pat))))
>                      #'(let ((val (hash-ref defined 'nm err)))
>                              (if (eq? val err)
>                                   (let ((val (make-regexp pat)))
>                                         (hash-set! defined 'nm val)
>                                          val)
>                                    val))))))))
>
> use it as
>
> #'(let ((id (rx pat)) ...)
>      (cond
>   ((regexp-exec id str) =>
> (lambda (m) (rx-let m (v ...) exp ...)))
> ...
>   (else else-exp ...)))))
>
> Ideally you should be able to generate the regexp at loading as you want
> to do but I don't think it is supported.
>
> Regards
> Stefan
>
>
> On Thu, Feb 11, 2016 at 5:28 AM, Matt Wette <matthew.we...@verizon.net>
> wrote:
>
>> I am trying to get a macro to expand at compile time using eval-when, but
>> it’s not giving me what I expect:
>>
>> (eval-when (expand) (make-regexp pat)) …
>>
>> gets expanded to:
>>
>>         (if #f #f)
>>
>> I would like to see something like
>>
>> #<regexp 1098a2d40>
>>
>> Any help would be appreciated. — Matt
>>
>> I get the same (if #f #f) result whether I use (expand) or (compile).
>>
>> Below is
>> 1) my macro (missing the helpers all-const-string? and rx-let)
>> 2) the macro I use to compile to il-tree and then back to scheme
>> 3) the demo code
>> 4) the output from expand
>>
>> === my macro ==========================
>> (define-syntax regexp-case
>>   (lambda (x)
>>     (syntax-case x (else)
>>       ((_ str ((pat v ...) exp ...) ... (else else-exp ...))
>>        (with-syntax (((id ...) (generate-temporaries #'(pat ...))))
>> (all-const-string? #'(pat ...))
>> #'(let ((id (eval-when (expand) (make-regexp pat))) ...)
>>     (cond
>>      ((regexp-exec id str) =>
>>       (lambda (m) (rx-let m (v ...) exp ...)))
>>      ...
>>      (else else-exp ...)))))
>>       ((_ str ((pat v ...) exp ...) ...)
>>        (with-syntax (((id ...) (generate-temporaries #'(pat ...))))
>> (all-const-string? #'(pat ...))
>> #'(let ((id (eval-when (expand) (make-regexp pat))) ...)
>>     (cond
>>      ((regexp-exec id str) =>
>>       (lambda (m) (rx-let m (v ...) exp ...)))
>>      ...
>>      (else
>>       (scm-error #f "regexp-case"
>>  "no match found: ~S" (list str)
>>  #f)))))))))
>>
>> === the expand macro =======================
>>
>> #:use-module (srfi srfi-11)
>>
>> #:use-module (system base compile)
>>
>>
>> (define* (expand-form e #:key (opts '()))
>>
>>   (let-values (((exp env) (decompile
>>
>>                            (compile e #:from 'scheme
>>
>>                                     #:to 'tree-il
>>
>>                                     #:env (current-module))
>>
>>                            #:from 'tree-il
>>
>>                            #:to 'scheme
>>
>>                            #:opts opts)))
>>
>>     exp))
>>
>>
>> (define-syntax-rule (expand _expression_)
>>
>>   (expand-form '_expression_))
>>
>> === orig test case ================
>>   (regexp-case str
>>     (("^([a-z]+)\\(([0-9]+)\\)$" v i)
>>      (list v i))
>>     (("^([a-z]+)$" v)
>>      (list v "1")))
>>
>> === output from expand =============
>>
>> (let ((t-768 (if #f #f))
>>
>>       (t-769 (if #f #f)))
>>
>>   (let ((t (regexp-exec t-768 str)))
>>
>>     (if t
>>
>>       (let ((m t))
>>
>>         (let ((v (match:substring m 1))
>>
>>               (i (match:substring m 2)))
>>
>>           (list v i)))
>>
>>       (let ((t (regexp-exec t-769 str)))
>>
>>         (if t
>>
>>           (let* ((m t) (v (match:substring m 1)))
>>
>>             (list v "1"))
>>
>>           (scm-error
>>
>>             #f
>>
>>             "regexp-case"
>>
>>             "no match found: ~S"
>>
>>             (list str)
>>
>>             #f))))))
>>
>>
>

Reply via email to