unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Stefan Israelsson Tampe <stefan.itampe@gmail.com>
To: Matt Wette <matthew.wette@verizon.net>
Cc: "guile-user@gnu.org" <guile-user@gnu.org>
Subject: Re: eval-when not giving me what I hoped for
Date: Thu, 11 Feb 2016 11:09:44 +0100	[thread overview]
Message-ID: <CAGua6m0NGiXTi_AytM7y5WTxVL9L9UE3sygk=s0yfbqDByXQZQ@mail.gmail.com> (raw)
In-Reply-To: <CAGua6m0YfEx1d7sZAKNzpjHOsSuhcnWAkacvZjkVJsxFetUHWw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 6228 bytes --]

Stupid email client, ... one more try

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)))
                     #'nm)))))

and use it as previous mail

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

> 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.itampe@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.wette@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))))))
>>>
>>>
>>
>

[-- Attachment #2: Type: text/html, Size: 15659 bytes --]

  reply	other threads:[~2016-02-11 10:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-11  4:28 eval-when not giving me what I hoped for Matt Wette
2016-02-11  9:37 ` Stefan Israelsson Tampe
2016-02-11 10:08   ` Stefan Israelsson Tampe
2016-02-11 10:09     ` Stefan Israelsson Tampe [this message]
2016-02-11 13:47   ` Matt Wette

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAGua6m0NGiXTi_AytM7y5WTxVL9L9UE3sygk=s0yfbqDByXQZQ@mail.gmail.com' \
    --to=stefan.itampe@gmail.com \
    --cc=guile-user@gnu.org \
    --cc=matthew.wette@verizon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).