sxml-match.ss 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. ;; Library: sxml-match
  2. ;; Author: Jim Bender
  3. ;; Version: 1.1, version for PLT Scheme
  4. ;;
  5. ;; Copyright 2005-9, Jim Bender
  6. ;; sxml-match is released under the MIT License
  7. ;;
  8. (module sxml-match mzscheme
  9. (provide sxml-match
  10. sxml-match-let
  11. sxml-match-let*)
  12. (require (rename (lib "fold.ss" "srfi" "1") fold-right fold-right)
  13. (rename (lib "filter.ss" "srfi" "1") filter filter))
  14. (define (nodeset? x)
  15. (or (and (pair? x) (not (symbol? (car x)))) (null? x)))
  16. (define (xml-element-tag s)
  17. (if (and (pair? s) (symbol? (car s)))
  18. (car s)
  19. (error 'xml-element-tag "expected an xml-element, given" s)))
  20. (define (xml-element-attributes s)
  21. (if (and (pair? s) (symbol? (car s)))
  22. (fold-right (lambda (a b)
  23. (if (and (pair? a) (eq? '@ (car a)))
  24. (if (null? b)
  25. (filter (lambda (i) (not (and (pair? i) (eq? '@ (car i))))) (cdr a))
  26. (fold-right (lambda (c d)
  27. (if (and (pair? c) (eq? '@ (car c)))
  28. d
  29. (cons c d)))
  30. b (cdr a)))
  31. b))
  32. '()
  33. (cdr s))
  34. (error 'xml-element-attributes "expected an xml-element, given" s)))
  35. (define (xml-element-contents s)
  36. (if (and (pair? s) (symbol? (car s)))
  37. (filter (lambda (i)
  38. (not (and (pair? i) (eq? '@ (car i)))))
  39. (cdr s))
  40. (error 'xml-element-contents "expected an xml-element, given" s)))
  41. (define (match-xml-attribute key l)
  42. (if (not (pair? l))
  43. #f
  44. (if (eq? (car (car l)) key)
  45. (car l)
  46. (match-xml-attribute key (cdr l)))))
  47. (define (filter-attributes keys lst)
  48. (if (null? lst)
  49. '()
  50. (if (member (caar lst) keys)
  51. (filter-attributes keys (cdr lst))
  52. (cons (car lst) (filter-attributes keys (cdr lst))))))
  53. (define-syntax compile-clause
  54. (lambda (stx)
  55. (letrec
  56. ([sxml-match-syntax-error
  57. (lambda (msg exp sub)
  58. (raise-syntax-error #f msg (with-syntax ([s exp]) (syntax (sxml-match s))) sub))]
  59. [ellipsis?
  60. (lambda (stx)
  61. (and (identifier? stx) (eq? '... (syntax-object->datum stx))))]
  62. [literal?
  63. (lambda (stx)
  64. (let ([x (syntax-object->datum stx)])
  65. (or (string? x)
  66. (char? x)
  67. (number? x)
  68. (boolean? x))))]
  69. [keyword?
  70. (lambda (stx)
  71. (and (identifier? stx)
  72. (let ([str (symbol->string (syntax-object->datum stx))])
  73. (char=? #\: (string-ref str (- (string-length str) 1))))))]
  74. [extract-cata-fun
  75. (lambda (cf)
  76. (syntax-case cf ()
  77. [#f #f]
  78. [other cf]))]
  79. [add-pat-var
  80. (lambda (pvar pvar-lst)
  81. (define (check-pvar lst)
  82. (if (null? lst)
  83. (void)
  84. (if (bound-identifier=? (car lst) pvar)
  85. (sxml-match-syntax-error "duplicate pattern variable not allowed"
  86. stx
  87. pvar)
  88. (check-pvar (cdr lst)))))
  89. (check-pvar pvar-lst)
  90. (cons pvar pvar-lst))]
  91. [add-cata-def
  92. (lambda (depth cvars cfun ctemp cdefs)
  93. (cons (list depth cvars cfun ctemp) cdefs))]
  94. [process-cata-exp
  95. (lambda (depth cfun ctemp)
  96. (if (= depth 0)
  97. (with-syntax ([cf cfun]
  98. [ct ctemp])
  99. (syntax (cf ct)))
  100. (let ([new-ctemp (car (generate-temporaries (list ctemp)))])
  101. (with-syntax ([ct ctemp]
  102. [nct new-ctemp]
  103. [body (process-cata-exp (- depth 1) cfun new-ctemp)])
  104. (syntax (map (lambda (nct) body) ct))))))]
  105. [process-cata-defs
  106. (lambda (cata-defs body)
  107. (if (null? cata-defs)
  108. body
  109. (with-syntax ([(cata-binding ...)
  110. (map (lambda (def)
  111. (with-syntax ([bvar (cadr def)]
  112. [bval (process-cata-exp (car def)
  113. (caddr def)
  114. (cadddr def))])
  115. (syntax (bvar bval))))
  116. cata-defs)]
  117. [body-stx body])
  118. (syntax (let-values (cata-binding ...)
  119. body-stx)))))]
  120. [cata-defs->pvar-lst
  121. (lambda (lst)
  122. (if (null? lst)
  123. '()
  124. (let iter ([items (cadr (car lst))])
  125. (syntax-case items ()
  126. [() (cata-defs->pvar-lst (cdr lst))]
  127. [(fst . rst) (cons (syntax fst) (iter (syntax rst)))]))))]
  128. [process-output-action
  129. (lambda (action dotted-vars)
  130. (define (finite-lst? lst)
  131. (syntax-case lst ()
  132. (item
  133. (identifier? (syntax item))
  134. #f)
  135. (()
  136. #t)
  137. ((fst dots . rst)
  138. (ellipsis? (syntax dots))
  139. #f)
  140. ((fst . rst)
  141. (finite-lst? (syntax rst)))))
  142. (define (expand-lst lst)
  143. (syntax-case lst ()
  144. [() (syntax '())]
  145. [item
  146. (identifier? (syntax item))
  147. (syntax item)]
  148. [(fst dots . rst)
  149. (ellipsis? (syntax dots))
  150. (with-syntax ([exp-lft (expand-dotted-item
  151. (process-output-action (syntax fst)
  152. dotted-vars))]
  153. [exp-rgt (expand-lst (syntax rst))])
  154. (syntax (append exp-lft exp-rgt)))]
  155. [(fst . rst)
  156. (with-syntax ([exp-lft (process-output-action (syntax fst)
  157. dotted-vars)]
  158. [exp-rgt (expand-lst (syntax rst))])
  159. (syntax (cons exp-lft exp-rgt)))]))
  160. (define (member-var? var lst)
  161. (let iter ([lst lst])
  162. (if (null? lst)
  163. #f
  164. (if (or (bound-identifier=? var (car lst))
  165. (free-identifier=? var (car lst)))
  166. #t
  167. (iter (cdr lst))))))
  168. (define (dotted-var? var)
  169. (member-var? var dotted-vars))
  170. (define (merge-pvars lst1 lst2)
  171. (if (null? lst1)
  172. lst2
  173. (if (member-var? (car lst1) lst2)
  174. (merge-pvars (cdr lst1) lst2)
  175. (cons (car lst1) (merge-pvars (cdr lst1) lst2)))))
  176. (define (select-dotted-vars x)
  177. (define (walk-quasi-body y)
  178. (syntax-case y (unquote unquote-splicing)
  179. [((unquote a) . rst)
  180. (merge-pvars (select-dotted-vars (syntax a))
  181. (walk-quasi-body (syntax rst)))]
  182. [((unquote-splicing a) . rst)
  183. (merge-pvars (select-dotted-vars (syntax a))
  184. (walk-quasi-body (syntax rst)))]
  185. [(fst . rst)
  186. (merge-pvars (walk-quasi-body (syntax fst))
  187. (walk-quasi-body (syntax rst)))]
  188. [other
  189. '()]))
  190. (syntax-case x (quote quasiquote)
  191. [(quote . rst) '()]
  192. [(quasiquote . rst) (walk-quasi-body (syntax rst))]
  193. [(fst . rst)
  194. (merge-pvars (select-dotted-vars (syntax fst))
  195. (select-dotted-vars (syntax rst)))]
  196. [item
  197. (and (identifier? (syntax item))
  198. (dotted-var? (syntax item)))
  199. (list (syntax item))]
  200. [item '()]))
  201. (define (expand-dotted-item item)
  202. (let ([dvars (select-dotted-vars item)])
  203. (syntax-case item ()
  204. [x
  205. (identifier? (syntax x))
  206. (syntax x)]
  207. [x (with-syntax ([(dv ...) dvars])
  208. (syntax (map (lambda (dv ...) x) dv ...)))])))
  209. (define (expand-quasiquote-body x)
  210. (syntax-case x (unquote unquote-splicing quasiquote)
  211. [(quasiquote . rst) (process-quasiquote x)]
  212. [(unquote item)
  213. (with-syntax ([expanded-item (process-output-action (syntax item)
  214. dotted-vars)])
  215. (syntax (unquote expanded-item)))]
  216. [(unquote-splicing item)
  217. (with-syntax ([expanded-item (process-output-action (syntax item)
  218. dotted-vars)])
  219. (syntax (unquote-splicing expanded-item)))]
  220. [((unquote item) dots . rst)
  221. (ellipsis? (syntax dots))
  222. (with-syntax ([expanded-item (expand-dotted-item
  223. (process-output-action (syntax item)
  224. dotted-vars))]
  225. [expanded-rst (expand-quasiquote-body (syntax rst))])
  226. (syntax ((unquote-splicing expanded-item) . expanded-rst)))]
  227. [(item dots . rst)
  228. (ellipsis? (syntax dots))
  229. (with-syntax ([expanded-item (expand-dotted-item
  230. (process-output-action (syntax (quasiquote item))
  231. dotted-vars))]
  232. [expanded-rst (expand-quasiquote-body (syntax rst))])
  233. (syntax ((unquote-splicing expanded-item) . expanded-rst)))]
  234. [(fst . rst)
  235. (with-syntax ([expanded-fst (expand-quasiquote-body (syntax fst))]
  236. [expanded-rst (expand-quasiquote-body (syntax rst))])
  237. (syntax (expanded-fst . expanded-rst)))]
  238. [other x]))
  239. (define (process-quasiquote x)
  240. (syntax-case x ()
  241. [(quasiquote term) (with-syntax ([expanded-body (expand-quasiquote-body (syntax term))])
  242. (syntax (quasiquote expanded-body)))]
  243. [else (sxml-match-syntax-error "bad quasiquote-form"
  244. stx
  245. x)]))
  246. (syntax-case action (quote quasiquote)
  247. [(quote . rst) action]
  248. [(quasiquote . rst) (process-quasiquote action)]
  249. [(fst . rst) (if (finite-lst? action)
  250. (with-syntax ([exp-lft (process-output-action (syntax fst) dotted-vars)]
  251. [exp-rgt (process-output-action (syntax rst) dotted-vars)])
  252. (syntax (exp-lft . exp-rgt)))
  253. (with-syntax ([exp-lft (process-output-action (syntax fst)
  254. dotted-vars)]
  255. [exp-rgt (expand-lst (syntax rst))])
  256. (syntax (apply exp-lft exp-rgt))))]
  257. [item action]))]
  258. [compile-element-pat
  259. (lambda (ele exp nextp fail-k pvar-lst depth cata-fun cata-defs dotted-vars)
  260. (syntax-case ele (@)
  261. [(tag (@ . attr-items) . items)
  262. (identifier? (syntax tag))
  263. (let ([attr-exp (car (generate-temporaries (list exp)))]
  264. [body-exp (car (generate-temporaries (list exp)))])
  265. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  266. (compile-attr-list (syntax attr-items)
  267. (syntax items)
  268. attr-exp
  269. body-exp
  270. '()
  271. nextp
  272. fail-k
  273. pvar-lst
  274. depth
  275. cata-fun
  276. cata-defs
  277. dotted-vars)])
  278. (values (with-syntax ([x exp]
  279. [ax attr-exp]
  280. [bx body-exp]
  281. [body tests]
  282. [fail-to fail-k])
  283. (syntax (if (and (pair? x) (eq? 'tag (xml-element-tag x)))
  284. (let ([ax (xml-element-attributes x)]
  285. [bx (xml-element-contents x)])
  286. body)
  287. (fail-to))))
  288. new-pvar-lst
  289. new-cata-defs
  290. new-dotted-vars)))]
  291. [(tag . items)
  292. (identifier? (syntax tag))
  293. (let ([body-exp (car (generate-temporaries (list exp)))])
  294. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  295. (compile-item-list (syntax items)
  296. body-exp
  297. nextp
  298. fail-k
  299. #t
  300. pvar-lst
  301. depth
  302. cata-fun
  303. cata-defs
  304. dotted-vars)])
  305. (values (with-syntax ([x exp]
  306. [bx body-exp]
  307. [body tests]
  308. [fail-to fail-k])
  309. (syntax (if (and (pair? x) (eq? 'tag (xml-element-tag x)))
  310. (let ([bx (xml-element-contents x)])
  311. body)
  312. (fail-to))))
  313. new-pvar-lst
  314. new-cata-defs
  315. new-dotted-vars)))]))]
  316. [compile-end-element
  317. (lambda (exp nextp fail-k pvar-lst cata-defs dotted-vars)
  318. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  319. (nextp pvar-lst cata-defs dotted-vars)])
  320. (values (with-syntax ([x exp]
  321. [body next-tests]
  322. [fail-to fail-k])
  323. (syntax (if (null? x) body (fail-to))))
  324. new-pvar-lst
  325. new-cata-defs
  326. new-dotted-vars)))]
  327. [compile-attr-list
  328. (lambda (attr-lst body-lst attr-exp body-exp attr-key-lst nextp fail-k pvar-lst depth cata-fun cata-defs dotted-vars)
  329. (syntax-case attr-lst (unquote ->)
  330. [(unquote var)
  331. (identifier? (syntax var))
  332. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  333. (compile-item-list body-lst
  334. body-exp
  335. nextp
  336. fail-k
  337. #t
  338. (add-pat-var (syntax var) pvar-lst)
  339. depth
  340. cata-fun
  341. cata-defs
  342. dotted-vars)])
  343. (values (with-syntax ([ax attr-exp]
  344. [matched-attrs attr-key-lst]
  345. [body tests])
  346. (syntax (let ([var (filter-attributes 'matched-attrs ax)])
  347. body)))
  348. new-pvar-lst
  349. new-cata-defs
  350. new-dotted-vars))]
  351. [((atag [(unquote [cata -> cvar ...]) default]) . rst)
  352. (identifier? (syntax atag))
  353. (let ([ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  354. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  355. (compile-attr-list (syntax rst)
  356. body-lst
  357. attr-exp
  358. body-exp
  359. (cons (syntax atag) attr-key-lst)
  360. nextp
  361. fail-k
  362. (add-pat-var ctemp pvar-lst)
  363. depth
  364. cata-fun
  365. (add-cata-def depth
  366. (syntax [cvar ...])
  367. (syntax cata)
  368. ctemp
  369. cata-defs)
  370. dotted-vars)])
  371. (values (with-syntax ([ax attr-exp]
  372. [ct ctemp]
  373. [body tests])
  374. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  375. (let ([ct (if binding
  376. (cadr binding)
  377. default)])
  378. body))))
  379. new-pvar-lst
  380. new-cata-defs
  381. new-dotted-vars)))]
  382. [((atag [(unquote [cvar ...]) default]) . rst)
  383. (identifier? (syntax atag))
  384. (let ([ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  385. (if (not cata-fun)
  386. (sxml-match-syntax-error "sxml-match pattern: catamorphism not allowed in this context"
  387. stx
  388. (syntax [cvar ...])))
  389. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  390. (compile-attr-list (syntax rst)
  391. body-lst
  392. attr-exp
  393. body-exp
  394. (cons (syntax atag) attr-key-lst)
  395. nextp
  396. fail-k
  397. (add-pat-var ctemp pvar-lst)
  398. depth
  399. cata-fun
  400. (add-cata-def depth
  401. (syntax [cvar ...])
  402. cata-fun
  403. ctemp
  404. cata-defs)
  405. dotted-vars)])
  406. (values (with-syntax ([ax attr-exp]
  407. [ct ctemp]
  408. [body tests])
  409. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  410. (let ([ct (if binding
  411. (cadr binding)
  412. default)])
  413. body))))
  414. new-pvar-lst
  415. new-cata-defs
  416. new-dotted-vars)))]
  417. [((atag [(unquote var) default]) . rst)
  418. (and (identifier? (syntax atag)) (identifier? (syntax var)))
  419. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  420. (compile-attr-list (syntax rst)
  421. body-lst
  422. attr-exp
  423. body-exp
  424. (cons (syntax atag) attr-key-lst)
  425. nextp
  426. fail-k
  427. (add-pat-var (syntax var) pvar-lst)
  428. depth
  429. cata-fun
  430. cata-defs
  431. dotted-vars)])
  432. (values (with-syntax ([ax attr-exp]
  433. [body tests])
  434. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  435. (let ([var (if binding
  436. (cadr binding)
  437. default)])
  438. body))))
  439. new-pvar-lst
  440. new-cata-defs
  441. new-dotted-vars))]
  442. [((atag (unquote [cata -> cvar ...])) . rst)
  443. (identifier? (syntax atag))
  444. (let ([ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  445. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  446. (compile-attr-list (syntax rst)
  447. body-lst
  448. attr-exp
  449. body-exp
  450. (cons (syntax atag) attr-key-lst)
  451. nextp
  452. fail-k
  453. (add-pat-var ctemp pvar-lst)
  454. depth
  455. cata-fun
  456. (add-cata-def depth
  457. (syntax [cvar ...])
  458. (syntax cata)
  459. ctemp
  460. cata-defs)
  461. dotted-vars)])
  462. (values (with-syntax ([ax attr-exp]
  463. [ct ctemp]
  464. [body tests]
  465. [fail-to fail-k])
  466. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  467. (if binding
  468. (let ([ct (cadr binding)])
  469. body)
  470. (fail-to)))))
  471. new-pvar-lst
  472. new-cata-defs
  473. new-dotted-vars)))]
  474. [((atag (unquote [cvar ...])) . rst)
  475. (identifier? (syntax atag))
  476. (let ([ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  477. (if (not cata-fun)
  478. (sxml-match-syntax-error "sxml-match pattern: catamorphism not allowed in this context"
  479. stx
  480. (syntax [cvar ...])))
  481. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  482. (compile-attr-list (syntax rst)
  483. body-lst
  484. attr-exp
  485. body-exp
  486. (cons (syntax atag) attr-key-lst)
  487. nextp
  488. fail-k
  489. (add-pat-var ctemp pvar-lst)
  490. depth
  491. cata-fun
  492. (add-cata-def depth
  493. (syntax [cvar ...])
  494. cata-fun
  495. ctemp
  496. cata-defs)
  497. dotted-vars)])
  498. (values (with-syntax ([ax attr-exp]
  499. [ct ctemp]
  500. [body tests]
  501. [fail-to fail-k])
  502. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  503. (if binding
  504. (let ([ct (cadr binding)])
  505. body)
  506. (fail-to)))))
  507. new-pvar-lst
  508. new-cata-defs
  509. new-dotted-vars)))]
  510. [((atag (unquote var)) . rst)
  511. (and (identifier? (syntax atag)) (identifier? (syntax var)))
  512. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  513. (compile-attr-list (syntax rst)
  514. body-lst
  515. attr-exp
  516. body-exp
  517. (cons (syntax atag) attr-key-lst)
  518. nextp
  519. fail-k
  520. (add-pat-var (syntax var) pvar-lst)
  521. depth
  522. cata-fun
  523. cata-defs
  524. dotted-vars)])
  525. (values (with-syntax ([ax attr-exp]
  526. [body tests]
  527. [fail-to fail-k])
  528. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  529. (if binding
  530. (let ([var (cadr binding)])
  531. body)
  532. (fail-to)))))
  533. new-pvar-lst
  534. new-cata-defs
  535. new-dotted-vars))]
  536. [((atag (i ...)) . rst)
  537. (identifier? (syntax atag))
  538. (sxml-match-syntax-error "bad attribute pattern"
  539. stx
  540. (syntax (kwd (i ...))))]
  541. [((atag i) . rst)
  542. (and (identifier? (syntax atag)) (identifier? (syntax i)))
  543. (sxml-match-syntax-error "bad attribute pattern"
  544. stx
  545. (syntax (kwd i)))]
  546. [((atag literal) . rst)
  547. (and (identifier? (syntax atag)) (literal? (syntax literal)))
  548. (let-values ([(tests new-pvar-lst new-cata-defs new-dotted-vars)
  549. (compile-attr-list (syntax rst)
  550. body-lst
  551. attr-exp
  552. body-exp
  553. (cons (syntax atag) attr-key-lst)
  554. nextp
  555. fail-k
  556. pvar-lst
  557. depth
  558. cata-fun
  559. cata-defs
  560. dotted-vars)])
  561. (values (with-syntax ([ax attr-exp]
  562. [body tests]
  563. [fail-to fail-k])
  564. (syntax (let ([binding (match-xml-attribute 'atag ax)])
  565. (if binding
  566. (if (equal? (cadr binding) literal)
  567. body
  568. (fail-to))
  569. (fail-to)))))
  570. new-pvar-lst
  571. new-cata-defs
  572. new-dotted-vars))]
  573. [()
  574. (compile-item-list body-lst
  575. body-exp
  576. nextp
  577. fail-k
  578. #t
  579. pvar-lst
  580. depth
  581. cata-fun
  582. cata-defs
  583. dotted-vars)]))]
  584. [compile-item-list
  585. (lambda (lst exp nextp fail-k ellipsis-allowed? pvar-lst depth cata-fun cata-defs dotted-vars)
  586. (syntax-case lst (unquote ->)
  587. [() (compile-end-element exp nextp fail-k pvar-lst cata-defs dotted-vars)]
  588. [(unquote var)
  589. (identifier? (syntax var))
  590. (if (not ellipsis-allowed?)
  591. (sxml-match-syntax-error "improper list pattern not allowed in this context"
  592. stx
  593. (syntax dots))
  594. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  595. (nextp (add-pat-var (syntax var) pvar-lst) cata-defs dotted-vars)])
  596. (values (with-syntax ([x exp]
  597. [body next-tests])
  598. (syntax (let ([var x]) body)))
  599. new-pvar-lst
  600. new-cata-defs
  601. new-dotted-vars)))]
  602. [(unquote [cata -> cvar ...])
  603. (if (not ellipsis-allowed?)
  604. (sxml-match-syntax-error "improper list pattern not allowed in this context"
  605. stx
  606. (syntax dots))
  607. (let ([ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  608. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  609. (nextp (add-pat-var ctemp pvar-lst)
  610. (add-cata-def depth
  611. (syntax [cvar ...])
  612. (syntax cata)
  613. ctemp
  614. cata-defs)
  615. dotted-vars)])
  616. (values (with-syntax ([ct ctemp]
  617. [x exp]
  618. [body next-tests])
  619. (syntax (let ([ct x]) body)))
  620. new-pvar-lst
  621. new-cata-defs
  622. new-dotted-vars))))]
  623. [(unquote [cvar ...])
  624. (let ([ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  625. (if (not cata-fun)
  626. (sxml-match-syntax-error "sxml-match pattern: catamorphism not allowed in this context"
  627. stx
  628. (syntax [cvar ...])))
  629. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  630. (nextp (add-pat-var ctemp pvar-lst)
  631. (add-cata-def depth
  632. (syntax [cvar ...])
  633. cata-fun
  634. ctemp
  635. cata-defs)
  636. dotted-vars)])
  637. (values (with-syntax ([ct ctemp]
  638. [x exp]
  639. [body next-tests])
  640. (syntax (let ([ct x]) body)))
  641. new-pvar-lst
  642. new-cata-defs
  643. new-dotted-vars)))]
  644. [(item dots . rst)
  645. (ellipsis? (syntax dots))
  646. (if (not ellipsis-allowed?)
  647. (sxml-match-syntax-error "ellipses not allowed in this context"
  648. stx
  649. (syntax dots))
  650. (compile-dotted-pattern-list (syntax item)
  651. (syntax rst)
  652. exp
  653. nextp
  654. fail-k
  655. pvar-lst
  656. depth
  657. cata-fun
  658. cata-defs
  659. dotted-vars))]
  660. [(item . rst)
  661. (compile-item (syntax item)
  662. exp
  663. (lambda (new-exp new-pvar-lst new-cata-defs new-dotted-vars)
  664. (compile-item-list (syntax rst)
  665. new-exp
  666. nextp
  667. fail-k
  668. ellipsis-allowed?
  669. new-pvar-lst
  670. depth
  671. cata-fun
  672. new-cata-defs
  673. new-dotted-vars))
  674. fail-k
  675. pvar-lst
  676. depth
  677. cata-fun
  678. cata-defs
  679. dotted-vars)]))]
  680. [compile-dotted-pattern-list
  681. (lambda (item
  682. tail
  683. exp
  684. nextp
  685. fail-k
  686. pvar-lst
  687. depth
  688. cata-fun
  689. cata-defs
  690. dotted-vars)
  691. (let-values ([(tail-tests tail-pvar-lst tail-cata-defs tail-dotted-vars)
  692. (compile-item-list tail
  693. (syntax lst)
  694. (lambda (new-pvar-lst new-cata-defs new-dotted-vars)
  695. (values (with-syntax ([(npv ...) new-pvar-lst])
  696. (syntax (values #t npv ...)))
  697. new-pvar-lst
  698. new-cata-defs
  699. new-dotted-vars))
  700. (syntax fail)
  701. #f
  702. '()
  703. depth
  704. '()
  705. '()
  706. dotted-vars)]
  707. [(item-tests item-pvar-lst item-cata-defs item-dotted-vars)
  708. (compile-item item
  709. (syntax lst)
  710. (lambda (new-exp new-pvar-lst new-cata-defs new-dotted-vars)
  711. (values (with-syntax ([(npv ...) new-pvar-lst])
  712. (syntax (values #t (cdr lst) npv ...)))
  713. new-pvar-lst
  714. new-cata-defs
  715. new-dotted-vars))
  716. (syntax fail)
  717. '()
  718. (+ 1 depth)
  719. cata-fun
  720. '()
  721. dotted-vars)])
  722. ; more here: check for duplicate pat-vars, cata-defs
  723. (let-values ([(final-tests final-pvar-lst final-cata-defs final-dotted-vars)
  724. (nextp (append tail-pvar-lst item-pvar-lst pvar-lst)
  725. (append tail-cata-defs item-cata-defs cata-defs)
  726. (append item-pvar-lst
  727. (cata-defs->pvar-lst item-cata-defs)
  728. tail-dotted-vars
  729. dotted-vars))])
  730. (let ([temp-item-pvar-lst (generate-temporaries item-pvar-lst)])
  731. (values
  732. (with-syntax
  733. ([x exp]
  734. [fail-to fail-k]
  735. [tail-body tail-tests]
  736. [item-body item-tests]
  737. [final-body final-tests]
  738. [(ipv ...) item-pvar-lst]
  739. [(gpv ...) temp-item-pvar-lst]
  740. [(tpv ...) tail-pvar-lst]
  741. [(item-void ...) (map (lambda (i) (syntax (void))) item-pvar-lst)]
  742. [(tail-void ...) (map (lambda (i) (syntax (void))) tail-pvar-lst)]
  743. [(item-null ...) (map (lambda (i) (syntax '())) item-pvar-lst)]
  744. [(item-cons ...) (map (lambda (a b)
  745. (with-syntax ([xa a]
  746. [xb b])
  747. (syntax (cons xa xb))))
  748. item-pvar-lst
  749. temp-item-pvar-lst)])
  750. (syntax (letrec ([match-tail
  751. (lambda (lst fail)
  752. tail-body)]
  753. [match-item
  754. (lambda (lst)
  755. (let ([fail (lambda ()
  756. (values #f
  757. lst
  758. item-void ...))])
  759. item-body))]
  760. [match-dotted
  761. (lambda (x)
  762. (let-values ([(tail-res tpv ...)
  763. (match-tail x
  764. (lambda ()
  765. (values #f
  766. tail-void ...)))])
  767. (if tail-res
  768. (values item-null ...
  769. tpv ...)
  770. (let-values ([(res new-x ipv ...) (match-item x)])
  771. (if res
  772. (let-values ([(gpv ... tpv ...)
  773. (match-dotted new-x)])
  774. (values item-cons ... tpv ...))
  775. (let-values ([(last-tail-res tpv ...)
  776. (match-tail x fail-to)])
  777. (values item-null ... tpv ...)))))))])
  778. (let-values ([(ipv ... tpv ...)
  779. (match-dotted x)])
  780. final-body))))
  781. final-pvar-lst
  782. final-cata-defs
  783. final-dotted-vars)))))]
  784. [compile-item
  785. (lambda (item exp nextp fail-k pvar-lst depth cata-fun cata-defs dotted-vars)
  786. (syntax-case item (unquote ->)
  787. ; normal pattern var
  788. [(unquote var)
  789. (identifier? (syntax var))
  790. (let ([new-exp (car (generate-temporaries (list exp)))])
  791. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  792. (nextp new-exp (add-pat-var (syntax var) pvar-lst) cata-defs dotted-vars)])
  793. (values (with-syntax ([x exp]
  794. [nx new-exp]
  795. [body next-tests]
  796. [fail-to fail-k])
  797. (syntax (if (pair? x)
  798. (let ([nx (cdr x)]
  799. [var (car x)])
  800. body)
  801. (fail-to))))
  802. new-pvar-lst
  803. new-cata-defs
  804. new-dotted-vars)))]
  805. ; named catamorphism
  806. [(unquote [cata -> cvar ...])
  807. (let ([new-exp (car (generate-temporaries (list exp)))]
  808. [ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  809. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  810. (nextp new-exp
  811. (add-pat-var ctemp pvar-lst)
  812. (add-cata-def depth
  813. (syntax [cvar ...])
  814. (syntax cata)
  815. ctemp
  816. cata-defs)
  817. dotted-vars)])
  818. (values (with-syntax ([x exp]
  819. [nx new-exp]
  820. [ct ctemp]
  821. [body next-tests]
  822. [fail-to fail-k])
  823. (syntax (if (pair? x)
  824. (let ([nx (cdr x)]
  825. [ct (car x)])
  826. body)
  827. (fail-to))))
  828. new-pvar-lst
  829. new-cata-defs
  830. new-dotted-vars)))]
  831. ; basic catamorphism
  832. [(unquote [cvar ...])
  833. (let ([new-exp (car (generate-temporaries (list exp)))]
  834. [ctemp (car (generate-temporaries (syntax ([cvar ...]))))])
  835. (if (not cata-fun)
  836. (sxml-match-syntax-error "sxml-match pattern: catamorphism not allowed in this context"
  837. stx
  838. (syntax [cvar ...])))
  839. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  840. (nextp new-exp
  841. (add-pat-var ctemp pvar-lst)
  842. (add-cata-def depth
  843. (syntax [cvar ...])
  844. cata-fun
  845. ctemp
  846. cata-defs)
  847. dotted-vars)])
  848. (values (with-syntax ([x exp]
  849. [nx new-exp]
  850. [ct ctemp]
  851. [body next-tests]
  852. [fail-to fail-k])
  853. (syntax (if (pair? x)
  854. (let ([nx (cdr x)]
  855. [ct (car x)])
  856. body)
  857. (fail-to))))
  858. new-pvar-lst
  859. new-cata-defs
  860. new-dotted-vars)))]
  861. [(tag item ...)
  862. (identifier? (syntax tag))
  863. (let ([new-exp (car (generate-temporaries (list exp)))])
  864. (let-values ([(after-tests after-pvar-lst after-cata-defs after-dotted-vars)
  865. (compile-element-pat (syntax (tag item ...))
  866. (with-syntax ([x exp])
  867. (syntax (car x)))
  868. (lambda (more-pvar-lst more-cata-defs more-dotted-vars)
  869. (let-values ([(next-tests new-pvar-lst
  870. new-cata-defs
  871. new-dotted-vars)
  872. (nextp new-exp
  873. more-pvar-lst
  874. more-cata-defs
  875. more-dotted-vars)])
  876. (values (with-syntax ([x exp]
  877. [nx new-exp]
  878. [body next-tests])
  879. (syntax (let ([nx (cdr x)])
  880. body)))
  881. new-pvar-lst
  882. new-cata-defs
  883. new-dotted-vars)))
  884. fail-k
  885. pvar-lst
  886. depth
  887. cata-fun
  888. cata-defs
  889. dotted-vars)])
  890. ; test that we are not at the end of an item-list, BEFORE
  891. ; entering tests for the element pattern (against the 'car' of the item-list)
  892. (values (with-syntax ([x exp]
  893. [body after-tests]
  894. [fail-to fail-k])
  895. (syntax (if (pair? x)
  896. body
  897. (fail-to))))
  898. after-pvar-lst
  899. after-cata-defs
  900. after-dotted-vars)))]
  901. [(i ...)
  902. (sxml-match-syntax-error "bad pattern syntax (not an element pattern)"
  903. stx
  904. (syntax (i ...)))]
  905. [i
  906. (identifier? (syntax i))
  907. (sxml-match-syntax-error "bad pattern syntax (symbol not allowed in this context)"
  908. stx
  909. (syntax i))]
  910. [literal
  911. (literal? (syntax literal))
  912. (let ([new-exp (car (generate-temporaries (list exp)))])
  913. (let-values ([(next-tests new-pvar-lst new-cata-defs new-dotted-vars)
  914. (nextp new-exp pvar-lst cata-defs dotted-vars)])
  915. (values (with-syntax ([x exp]
  916. [nx new-exp]
  917. [body next-tests]
  918. [fail-to fail-k])
  919. (syntax (if (and (pair? x) (equal? literal (car x)))
  920. (let ([nx (cdr x)])
  921. body)
  922. (fail-to))))
  923. new-pvar-lst
  924. new-cata-defs
  925. new-dotted-vars)))]))])
  926. (let ([fail-k (syntax failure)])
  927. (syntax-case stx (unquote guard ->)
  928. [(compile-clause ((unquote var) (guard gexp ...) action0 action ...)
  929. exp
  930. cata-fun
  931. fail-exp)
  932. (identifier? (syntax var))
  933. (syntax (let ([var exp])
  934. (if (and gexp ...)
  935. (begin action0 action ...)
  936. (fail-exp))))]
  937. [(compile-clause ((unquote [cata -> cvar ...]) (guard gexp ...) action0 action ...)
  938. exp
  939. cata-fun
  940. fail-exp)
  941. (syntax (if (and gexp ...)
  942. (let-values ([(cvar ...) (cata exp)])
  943. (begin action0 action ...))
  944. (fail-exp)))]
  945. [(compile-clause ((unquote [cvar ...]) (guard gexp ...) action0 action ...)
  946. exp
  947. cata-fun
  948. fail-exp)
  949. (if (not (extract-cata-fun (syntax cata-fun)))
  950. (sxml-match-syntax-error "sxml-match pattern: catamorphism not allowed in this context"
  951. stx
  952. (syntax [cvar ...]))
  953. (syntax (if (and gexp ...)
  954. (let-values ([(cvar ...) (cata-fun exp)])
  955. (begin action0 action ...))
  956. (fail-exp))))]
  957. [(compile-clause ((unquote var) action0 action ...) exp cata-fun fail-exp)
  958. (identifier? (syntax var))
  959. (syntax (let ([var exp])
  960. action0 action ...))]
  961. [(compile-clause ((unquote [cata -> cvar ...]) action0 action ...) exp cata-fun fail-exp)
  962. (syntax (let-values ([(cvar ...) (cata exp)])
  963. action0 action ...))]
  964. [(compile-clause ((unquote [cvar ...]) action0 action ...) exp cata-fun fail-exp)
  965. (if (not (extract-cata-fun (syntax cata-fun)))
  966. (sxml-match-syntax-error "sxml-match pattern: catamorphism not allowed in this context"
  967. stx
  968. (syntax [cvar ...]))
  969. (syntax (let-values ([(cvar ...) (cata-fun exp)])
  970. action0 action ...)))]
  971. [(compile-clause ((lst . rst) (guard gexp ...) action0 action ...) exp cata-fun fail-exp)
  972. (and (identifier? (syntax lst)) (eq? 'list (syntax-object->datum (syntax lst))))
  973. (let-values ([(result pvar-lst cata-defs dotted-vars)
  974. (compile-item-list (syntax rst)
  975. (syntax exp)
  976. (lambda (new-pvar-lst new-cata-defs new-dotted-vars)
  977. (values
  978. (with-syntax
  979. ([exp-body (process-cata-defs new-cata-defs
  980. (process-output-action
  981. (syntax (begin action0
  982. action ...))
  983. new-dotted-vars))]
  984. [fail-to fail-k])
  985. (syntax (if (and gexp ...) exp-body (fail-to))))
  986. new-pvar-lst
  987. new-cata-defs
  988. new-dotted-vars))
  989. fail-k
  990. #t
  991. '()
  992. 0
  993. (extract-cata-fun (syntax cata-fun))
  994. '()
  995. '())])
  996. (with-syntax ([fail-to fail-k]
  997. [body result])
  998. (syntax (let ([fail-to fail-exp])
  999. (if (nodeset? exp)
  1000. body
  1001. (fail-to))))))]
  1002. [(compile-clause ((lst . rst) action0 action ...) exp cata-fun fail-exp)
  1003. (and (identifier? (syntax lst)) (eq? 'list (syntax-object->datum (syntax lst))))
  1004. (let-values ([(result pvar-lst cata-defs dotted-vars)
  1005. (compile-item-list (syntax rst)
  1006. (syntax exp)
  1007. (lambda (new-pvar-lst new-cata-defs new-dotted-vars)
  1008. (values (process-cata-defs new-cata-defs
  1009. (process-output-action
  1010. (syntax (begin action0
  1011. action ...))
  1012. new-dotted-vars))
  1013. new-pvar-lst
  1014. new-cata-defs
  1015. new-dotted-vars))
  1016. fail-k
  1017. #t
  1018. '()
  1019. 0
  1020. (extract-cata-fun (syntax cata-fun))
  1021. '()
  1022. '())])
  1023. (with-syntax ([body result]
  1024. [fail-to fail-k])
  1025. (syntax (let ([fail-to fail-exp])
  1026. (if (nodeset? exp)
  1027. body
  1028. (fail-to))))))]
  1029. [(compile-clause ((fst . rst) (guard gexp ...) action0 action ...) exp cata-fun fail-exp)
  1030. (identifier? (syntax fst))
  1031. (let-values ([(result pvar-lst cata-defs dotted-vars)
  1032. (compile-element-pat (syntax (fst . rst))
  1033. (syntax exp)
  1034. (lambda (new-pvar-lst new-cata-defs new-dotted-vars)
  1035. (values
  1036. (with-syntax
  1037. ([body (process-cata-defs new-cata-defs
  1038. (process-output-action
  1039. (syntax (begin action0
  1040. action ...))
  1041. new-dotted-vars))]
  1042. [fail-to fail-k])
  1043. (syntax (if (and gexp ...) body (fail-to))))
  1044. new-pvar-lst
  1045. new-cata-defs
  1046. new-dotted-vars))
  1047. fail-k
  1048. '()
  1049. 0
  1050. (extract-cata-fun (syntax cata-fun))
  1051. '()
  1052. '())])
  1053. (with-syntax ([fail-to fail-k]
  1054. [body result])
  1055. (syntax (let ([fail-to fail-exp])
  1056. body))))]
  1057. [(compile-clause ((fst . rst) action0 action ...) exp cata-fun fail-exp)
  1058. (identifier? (syntax fst))
  1059. (let-values ([(result pvar-lst cata-defs dotted-vars)
  1060. (compile-element-pat (syntax (fst . rst))
  1061. (syntax exp)
  1062. (lambda (new-pvar-lst new-cata-defs new-dotted-vars)
  1063. (values (process-cata-defs new-cata-defs
  1064. (process-output-action
  1065. (syntax (begin action0
  1066. action ...))
  1067. new-dotted-vars))
  1068. new-pvar-lst
  1069. new-cata-defs
  1070. new-dotted-vars))
  1071. fail-k
  1072. '()
  1073. 0
  1074. (extract-cata-fun (syntax cata-fun))
  1075. '()
  1076. '())])
  1077. (with-syntax ([fail-to fail-k]
  1078. [body result])
  1079. (syntax (let ([fail-to fail-exp])
  1080. body))))]
  1081. [(compile-clause ((i ...) (guard gexp ...) action0 action ...) exp cata-fun fail-exp)
  1082. (sxml-match-syntax-error "bad pattern syntax (not an element pattern)"
  1083. stx
  1084. (syntax (i ...)))]
  1085. [(compile-clause ((i ...) action0 action ...) exp cata-fun fail-exp)
  1086. (sxml-match-syntax-error "bad pattern syntax (not an element pattern)"
  1087. stx
  1088. (syntax (i ...)))]
  1089. [(compile-clause (pat (guard gexp ...) action0 action ...) exp cata-fun fail-exp)
  1090. (identifier? (syntax pat))
  1091. (sxml-match-syntax-error "bad pattern syntax (symbol not allowed in this context)"
  1092. stx
  1093. (syntax pat))]
  1094. [(compile-clause (pat action0 action ...) exp cata-fun fail-exp)
  1095. (identifier? (syntax pat))
  1096. (sxml-match-syntax-error "bad pattern syntax (symbol not allowed in this context)"
  1097. stx
  1098. (syntax pat))]
  1099. [(compile-clause (literal (guard gexp ...) action0 action ...) exp cata-fun fail-exp)
  1100. (literal? (syntax literal))
  1101. (syntax (if (and (equal? literal exp) (and gexp ...))
  1102. (begin action0 action ...)
  1103. (fail-exp)))]
  1104. [(compile-clause (literal action0 action ...) exp cata-fun fail-exp)
  1105. (literal? (syntax literal))
  1106. (syntax (if (equal? literal exp)
  1107. (begin action0 action ...)
  1108. (fail-exp)))])))))
  1109. (define-syntax sxml-match1
  1110. (syntax-rules ()
  1111. [(sxml-match1 exp cata-fun clause)
  1112. (compile-clause clause exp cata-fun
  1113. (lambda () (error 'sxml-match "no matching clause found")))]
  1114. [(sxml-match1 exp cata-fun clause0 clause ...)
  1115. (let/ec escape
  1116. (compile-clause clause0 exp cata-fun
  1117. (lambda () (call-with-values
  1118. (lambda () (sxml-match1 exp cata-fun
  1119. clause ...))
  1120. escape))))]))
  1121. (define-syntax sxml-match
  1122. (syntax-rules ()
  1123. ((sxml-match val clause0 clause ...)
  1124. (letrec ([cfun (lambda (exp)
  1125. (sxml-match1 exp cfun clause0 clause ...))])
  1126. (cfun val)))))
  1127. (define-syntax sxml-match-let1
  1128. (syntax-rules ()
  1129. [(sxml-match-let1 syntag synform () body0 body ...)
  1130. (let () body0 body ...)]
  1131. [(sxml-match-let1 syntag synform ([pat exp]) body0 body ...)
  1132. (compile-clause (pat (let () body0 body ...))
  1133. exp
  1134. #f
  1135. (lambda () (error 'syntag "could not match pattern ~s" 'pat)))]
  1136. [(sxml-match-let1 syntag synform ([pat0 exp0] [pat exp] ...) body0 body ...)
  1137. (compile-clause (pat0 (sxml-match-let1 syntag synform ([pat exp] ...) body0 body ...))
  1138. exp0
  1139. #f
  1140. (lambda () (error 'syntag "could not match pattern ~s" 'pat0)))]))
  1141. (define-syntax sxml-match-let-help
  1142. (lambda (stx)
  1143. (syntax-case stx ()
  1144. [(sxml-match-let-help syntag synform ([pat exp] ...) body0 body ...)
  1145. (with-syntax ([(temp-name ...) (generate-temporaries (syntax (exp ...)))])
  1146. (syntax (let ([temp-name exp] ...)
  1147. (sxml-match-let1 syntag synform ([pat temp-name] ...) body0 body ...))))])))
  1148. (define-syntax sxml-match-let
  1149. (lambda (stx)
  1150. (syntax-case stx ()
  1151. [(sxml-match-let ([pat exp] ...) body0 body ...)
  1152. (with-syntax ([synform stx])
  1153. (syntax (sxml-match-let-help sxml-match-let synform ([pat exp] ...) body0 body ...)))])))
  1154. (define-syntax sxml-match-let*
  1155. (lambda (stx)
  1156. (syntax-case stx ()
  1157. [(sxml-match-let* () body0 body ...)
  1158. (syntax (let () body0 body ...))]
  1159. [(sxml-match-let* ([pat0 exp0] [pat exp] ...) body0 body ...)
  1160. (with-syntax ([synform stx])
  1161. (syntax (sxml-match-let-help sxml-match-let* synform ([pat0 exp0])
  1162. (sxml-match-let* ([pat exp] ...)
  1163. body0 body ...))))])))
  1164. )