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