|
From: | Stefan Israelsson Tampe |
Subject: | Re: eval-when not giving me what I hoped for |
Date: | Thu, 11 Feb 2016 11:08:24 +0100 |
the result of eval-when will be available only att specified phases. So your eval-when code will not be availableexcept at expansion. Also it looks like you want to precompile the regexes. This is not a stupid idea and shouldbe 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.RegardsStefanOn Thu, Feb 11, 2016 at 5:28 AM, Matt Wette <address@hidden> 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. — MattI get the same (if #f #f) result whether I use (expand) or (compile).Below is1) 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 scheme3) the demo code4) 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))))))
[Prev in Thread] | Current Thread | [Next in Thread] |