unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* eval-when not giving me what I hoped for
@ 2016-02-11  4:28 Matt Wette
  2016-02-11  9:37 ` Stefan Israelsson Tampe
  0 siblings, 1 reply; 5+ messages in thread
From: Matt Wette @ 2016-02-11  4:28 UTC (permalink / raw
  To: guile-user

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

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: 12498 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: eval-when not giving me what I hoped for
  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 13:47   ` Matt Wette
  0 siblings, 2 replies; 5+ messages in thread
From: Stefan Israelsson Tampe @ 2016-02-11  9:37 UTC (permalink / raw
  To: Matt Wette; +Cc: guile-user@gnu.org

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

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: 11972 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: eval-when not giving me what I hoped for
  2016-02-11  9:37 ` Stefan Israelsson Tampe
@ 2016-02-11 10:08   ` Stefan Israelsson Tampe
  2016-02-11 10:09     ` Stefan Israelsson Tampe
  2016-02-11 13:47   ` Matt Wette
  1 sibling, 1 reply; 5+ messages in thread
From: Stefan Israelsson Tampe @ 2016-02-11 10:08 UTC (permalink / raw
  To: Matt Wette; +Cc: guile-user@gnu.org

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

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: 13943 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: eval-when not giving me what I hoped for
  2016-02-11 10:08   ` Stefan Israelsson Tampe
@ 2016-02-11 10:09     ` Stefan Israelsson Tampe
  0 siblings, 0 replies; 5+ messages in thread
From: Stefan Israelsson Tampe @ 2016-02-11 10:09 UTC (permalink / raw
  To: Matt Wette; +Cc: guile-user@gnu.org

[-- 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 --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: eval-when not giving me what I hoped for
  2016-02-11  9:37 ` Stefan Israelsson Tampe
  2016-02-11 10:08   ` Stefan Israelsson Tampe
@ 2016-02-11 13:47   ` Matt Wette
  1 sibling, 0 replies; 5+ messages in thread
From: Matt Wette @ 2016-02-11 13:47 UTC (permalink / raw
  To: guile-user


> On Feb 11, 2016, at 1: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.
> 

There is a load option to eval-when.  I can try that but I need to think about how to test it. — Matt




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-02-11 13:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2016-02-11 13:47   ` Matt Wette

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).