From: Matt Wette <mwette@alumni.caltech.edu>
To: guile-user@gnu.org
Subject: syncase code issue 1.8.8 -> 2.0.11
Date: Wed, 17 Sep 2014 18:18:05 -0700 [thread overview]
Message-ID: <2097C007-9993-4AA1-A5F7-209A7DADD6CE@alumni.caltech.edu> (raw)
[-- Attachment #1: Type: text/plain, Size: 2225 bytes --]
Hi Folks,
Anyone interested in looking at my syntax-case code? I wrote this several years ago under 1.8.8. Now moving to 2.0.11: not working :(.
Matt
This uses syntax-case. It works in 1.8.8, but I get errors in 2.0.11. I'm guessing I don't understand something about syntax-case in R6RS. I learned (or mislearned) syntax-case from the papers by Kent Dybvig, not from the R6RS spec.
Here is what I'm trying to do:
@item define-tokenizer name (rex1 tok1) (rex2 tok2) ...
Define tokenizer for which one can build string tokenizers.
Example:
(define-tokenizer tokiz ("[0-9]+" #\1) ("[a-z]+" #\a))
(define mt (make-tokiz "abc=def"))
(tokiz-latok mt) -> #\a
(tokiz-laval mt) -> "abc"
(tokiz-match mt #\a)
(tokiz-latok mt) -> #\=
In 1.8.8, I get the above output. In 2.0.11 I get
Syntax-case macros are now a part of Guile core; importing (ice-9 syncase) is no longer necessary. <=(no issue here)
ice-9/psyntax.scm:1274:12: In procedure dobody:
ice-9/psyntax.scm:1274:12: Syntax error:
u1.scm:106:18: definition in expression context, where definitions are not allowed, in form
(define make-tokiz
(lambda (string)
(let ((pobj (vector string 0 (string-length string) #\nul "")))
(tokiz-match pobj #\nul) pobj)))
Here is synopsis of the code (see attached for all of it):
(define-syntax define-tokenizer
;; pobj = parse object = #(string ix nd latok laval)
(lambda (x)
(syntax-case x ()
((_ name (c1 r1) ...)
(with-syntax ((maker (sc-gen-id (syntax name) "make-" (syntax name)))
...
)
(syntax
(begin
(define maker
(lambda (string)
(let ((pobj (vector string 0 (string-length string) #\nul "")))
(match pobj #\nul) ; prime latok/laval in parse-object
pobj)))
.....
)))))
(define sc-gen-id ;; (gc-gen-id (syntax name) "make-" (syntax name)) where name=foo -> make-foo
(lambda (template-id . args)
(datum->syntax-object template-id
(string->symbol
(apply string-append
(map (lambda (x)
(if (string? x) x
(symbol->string (syntax-object->datum x))))
args))))))
[-- Attachment #2: u1.scm --]
[-- Type: application/octet-stream, Size: 3839 bytes --]
(use-modules (ice-9 regex))
(use-modules (ice-9 format))
(use-modules (ice-9 syncase))
;; @item sc-gen-id template-id . args
;; For use in syntax-case/with-syntax, generates an identifier given
;; template-identifier and pattern from remaining args of symbol or string.
;; Example:
;; (sc-gen-id (syntax name) (syntax name) "-setter") -> foo-setter
;; where (syntax name) is 'foo
(define sc-gen-id
(lambda (template-id . args)
(datum->syntax-object template-id
(string->symbol
(apply string-append
(map (lambda (x)
(if (string? x) x
(symbol->string (syntax-object->datum x))))
args))))))
;; @item define-tokenizer name (rex1 tok1) (rex2 tok2) ...
;; Define tokenizer for which one can build string tokenizers.
;; (define t (make-name string)) generates the tokenizer for the string.
;; (name-latok t) returns the lookahead token, a character.
;; (name-laval t) returns the lookahead value, a string.
;; The end-of-string results in latok of #\nul, laval of "".
;; Example:
;; (define-tokenizer tokiz ("[0-9]+" #\1) ("[a-z]+" #\a))
;; (define mt (make-tokiz "abc=def"))
;; (tokiz-latok mt) -> #\a
;; (tokiz-laval mt) -> "abc"
;; (tokiz-match mt #\a)
;; (tokiz-latok mt) -> #\=
;; (tokiz-match mt #\=)
(define-syntax define-tokenizer
;; pobj = parse object = #(string ix nd latok laval)
(lambda (x)
(syntax-case x ()
((_ name (c1 r1) ...)
(with-syntax ((maker (sc-gen-id (syntax name) "make-" (syntax name)))
(latok (sc-gen-id (syntax name) (syntax name) "-latok"))
(laval (sc-gen-id (syntax name) (syntax name) "-laval"))
(match (sc-gen-id (syntax name) (syntax name) "-match"))
((def ...)
(let f ((ix 1)
(cz (syntax (c1 ...)))
(rz (syntax (r1 ...))))
(if (null? cz) '()
(cons (list (sc-gen-id
(car cz) "pat-" (number->string ix))
(list
make-regexp
(list string-append "^" (car cz))))
(f (+ 1 ix) (cdr cz) (cdr rz))))))
((v1 ...)
(let f ((ix 1)
(cz (syntax (c1 ...)))
(rz (syntax (r1 ...))))
(if (null? cz) '()
(cons (sc-gen-id
(car cz) "pat-" (number->string ix))
(f (+ 1 ix) (cdr cz) (cdr rz)))))))
(syntax
(begin
(define maker
(lambda (string)
(let ((pobj (vector string 0 (string-length string) #\nul "")))
(match pobj #\nul) ; prime latok/laval in parse-object
pobj)))
(define latok (lambda (pobj) (vector-ref pobj 3)))
(define laval (lambda (pobj) (vector-ref pobj 4)))
(define match
(let (def ...)
(lambda (pobj tokn)
(if (not (eq? tokn (latok pobj))) (error "syntax error"))
;; Shift.
(vector-set! pobj 1 (+ (vector-ref pobj 1)
(string-length (vector-ref pobj 4))))
;; Find new latok/laval.
(let* ((ps (substring (vector-ref pobj 0)
(vector-ref pobj 1)
(vector-ref pobj 2)))
(pc (if (eq? (vector-ref pobj 1)
(vector-ref pobj 2)) #\nul
(string-ref (vector-ref pobj 0)
(vector-ref pobj 1))))
(ms (lambda (rx) (regexp-exec rx ps)))
(set-la (lambda (tok val) ; set and return
(vector-set! pobj 3 tok)
(vector-set! pobj 4 val)
tok)))
;; next lookahead
(let iter ((vs (list v1 ...)) (rs (list r1 ...)))
(cond
((eq? (vector-ref pobj 1) (vector-ref pobj 2)) ; end
(set-la #\nul ""))
((null? vs) ; character
(set-la pc (string pc)))
((ms (car vs)) => ; pattern
(lambda (m)
(set-la (car rs) (match:substring m))))
(else
(iter (cdr vs) (cdr rs))))))))))))))))
(format #t "~a\n" (define-tokenizer tokiz ("[0-9]+" #\1) ("[a-z]+" #\a)))
(format #t "~a\n" (define mt (make-tokiz "abc=def")))
(format #t "~a\n" (tokiz-latok mt))
(format #t "~a\n" (tokiz-laval mt))
(format #t "~a\n" (tokiz-match mt #\a))
next reply other threads:[~2014-09-18 1:18 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-18 1:18 Matt Wette [this message]
2014-09-18 7:49 ` syncase code issue 1.8.8 -> 2.0.11 Panicz Maciej Godek
2014-09-18 10:20 ` Taylan Ulrich Bayirli/Kammer
2014-09-18 12:35 ` Matt Wette
-- strict thread matches above, loose matches on Subject: below --
2014-09-18 14:08 mwette
2014-09-19 3:54 ` 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=2097C007-9993-4AA1-A5F7-209A7DADD6CE@alumni.caltech.edu \
--to=mwette@alumni.caltech.edu \
--cc=guile-user@gnu.org \
/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).