magic-base.scm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. (define exit (lambda () (builtin exit)))
  2. (define gensym (lambda (x) (builtin gensym x)))
  3. (define display (lambda (x) (builtin display x)))
  4. (define newline (lambda () (builtin newline)))
  5. ;(define print (lambda (x) (builtin print x)))
  6. (define eq? (lambda (x y) (builtin eq? x y)))
  7. ;(define equal? (lambda (x y) (builtin equal? x y)))
  8. (define cons (lambda (x y) (builtin cons x y)))
  9. (define car (lambda (x) (builtin car x)))
  10. (define cdr (lambda (x) (builtin cdr x)))
  11. (define set-car! (lambda (x y) (builtin set-car! x y)))
  12. (define set-cdr! (lambda (x y) (builtin set-cdr! x y)))
  13. (define null? (lambda (x) (builtin null? x)))
  14. (define pair? (lambda (x) (builtin pair? x)))
  15. (define number? (lambda (x) (builtin number? x)))
  16. (define boolean? (lambda (x) (builtin boolean? x)))
  17. (define string? (lambda (x) (builtin string? x)))
  18. (define char? (lambda (x) (builtin char? x)))
  19. (define symbol? (lambda (x) (builtin symbol? x)))
  20. (define + (lambda (x y) (builtin + x y)))
  21. (define - (lambda (x y) (builtin - x y)))
  22. (define * (lambda (x y) (builtin * x y)))
  23. (define = (lambda (x y) (builtin = x y)))
  24. (define < (lambda (x y) (builtin < x y)))
  25. (define > (lambda (x y) (builtin > x y)))
  26. (define <= (lambda (x y) (builtin <= x y)))
  27. (define >= (lambda (x y) (builtin >= x y)))
  28. (define quotient (lambda (x y) (builtin quotient x y)))
  29. (define modulo (lambda (x y) (builtin modulo x y)))
  30. ;(define box (lambda (x) (builtin box x)))
  31. ;(define unbox (lambda (x) (builtin unbox x)))
  32. ;(define set-box! (lambda (x y) (builtin set-box! x y)))
  33. (define vector-ref (lambda (v i) (builtin vector-ref v i)))
  34. (define vector-set! (lambda (v i e) (builtin vector-set! v i e)))
  35. (define make-vector (lambda (l d) (builtin make-vector l d)))
  36. (define vector-length (lambda (v) (builtin vector-length v)))
  37. ;(define string->list (lambda (s) (builtin string->list s)))
  38. ;(define symbol->string (lambda (s) (builtin symbol->string s)))
  39. ;(define list->string (lambda (s) (builtin list->string s)))
  40. (define make-string (lambda (siz ch) (builtin make-string siz ch)))
  41. (define string-set! (lambda (s i chr) (builtin string-set! s i chr)))
  42. (define string-ref (lambda (s i) (builtin string-ref s i)))
  43. (define string->symbol (lambda (s) (builtin string->symbol s)))
  44. (define string-length (lambda (s) (builtin string-length s)))
  45. (define string=? (lambda (s t) (builtin string=? s t)))
  46. ;(define string->number (lambda (s) (builtin string->number s)))
  47. (define eof-object? (lambda (s) (builtin eof-object? s)))
  48. (define read-char (lambda () (builtin read-char)))
  49. (define peek-char (lambda () (builtin peek-char)))
  50. (define vector? (lambda (x) (builtin vector? x)))
  51. (define symbol->string (lambda (x) (builtin symbol->string x)))
  52. (define char->integer (lambda (x) (builtin char->integer x)))
  53. (define (caar x) (car (car x)))
  54. (define (cadr x) (car (cdr x)))
  55. (define (cdar x) (cdr (car x)))
  56. (define (cddr x) (cdr (cdr x)))
  57. (define (caaar x) (car (car (car x))))
  58. (define (caadr x) (car (car (cdr x))))
  59. (define (cadar x) (car (cdr (car x))))
  60. (define (caddr x) (car (cdr (cdr x))))
  61. (define (cdaar x) (cdr (car (car x))))
  62. (define (cdadr x) (cdr (car (cdr x))))
  63. (define (cddar x) (cdr (cdr (car x))))
  64. (define (cdddr x) (cdr (cdr (cdr x))))
  65. (define (cadddr x) (car (cdddr x)))
  66. (define (equal? x y)
  67. (if (pair? x)
  68. (if (pair? y)
  69. (if (equal? (car x) (car y))
  70. (equal? (cdr x) (cdr y))
  71. #f)
  72. #f)
  73. (eq? x y)))
  74. (define (not p) (if p #f #t))
  75. (define (length l)
  76. (if (null? l)
  77. 0
  78. (+ 1 (length (cdr l)))))
  79. (define (append x y)
  80. (if (null? x)
  81. y
  82. (cons (car x) (append (cdr x) y))))
  83. (define (revappend l r)
  84. (if (null? l)
  85. r
  86. (revappend (cdr l) (cons (car l) r))))
  87. (define (reverse l) (revappend l '()))
  88. (define (member elt l)
  89. (if (null? l)
  90. #f
  91. (if (eq? elt (car l))
  92. #t
  93. (member elt (cdr l)))))
  94. (define (filter p l)
  95. (if (null? l)
  96. '()
  97. (if (p (car l))
  98. (cons (car l) (filter p (cdr l)))
  99. (filter p (cdr l)))))
  100. (define (zero? n) (= n 0))
  101. (define (even? n) (= 0 (modulo n 2)))
  102. (define (odd? n) (not (even? n)))
  103. (define (list? l)
  104. (if (null? l)
  105. #t
  106. (if (pair? l)
  107. #t
  108. #f)))
  109. (define (for-each proc l)
  110. (if (null? l)
  111. #t
  112. (begin (proc (car l))
  113. (for-each proc (cdr l)))))
  114. (define (map f l)
  115. (if (null? l)
  116. '()
  117. (cons (f (car l))
  118. (map f (cdr l)))))
  119. (define (concat-map func lst)
  120. (if (null? lst)
  121. '()
  122. (append (func (car lst))
  123. (concat-map func (cdr lst)))))
  124. (define (assoc key tbl)
  125. (if (null? tbl)
  126. #f
  127. (if (eq? key (caar tbl))
  128. (car tbl)
  129. (assoc key (cdr tbl)))))
  130. (define (error x y z)
  131. ; (print x)
  132. ; (print y)
  133. ; (print z)
  134. (builtin exit)
  135. )
  136. ;(define (print p) (display p) (newline))
  137. ;; OR and AND
  138. (define (list1 y) (cons y '()))
  139. (define (list2 x y) (cons x (cons y '())))
  140. (define (list3 x y z) (cons x (cons y (cons z '()))))
  141. (define (list4 x y z w) (cons x (cons y (cons z (cons w '())))))
  142. (defmacro or
  143. (lambda (exp)
  144. (if (null? (cdr exp))
  145. ;; (or)
  146. #f
  147. (if (null? (cddr exp))
  148. ;; (or v)
  149. (cadr exp)
  150. ;; (or ,v . ,vs)
  151. (let ((v (cadr exp))
  152. (vs (cddr exp))
  153. (tmp (gensym 'or-tmp)))
  154. (list3 'let (list1 (list2 tmp v))
  155. (list4 'if tmp
  156. tmp
  157. (builtin cons 'or vs))))))))
  158. (defmacro and
  159. (lambda (exp)
  160. (if (null? (cdr exp))
  161. ;; (and)
  162. #t
  163. (if (null? (cddr exp))
  164. ;; (and v)
  165. (cadr exp)
  166. ;; (and ,v . ,vs)
  167. (let ((v (cadr exp))
  168. (vs (cddr exp))
  169. (tmp (gensym 'or-tmp)))
  170. (list3 'let (list1 (list2 tmp v))
  171. (list4 'if tmp
  172. (builtin cons 'and vs)
  173. #f)))))))
  174. ;; QUASIQUOTE AND UNQUOTE
  175. (define (unquote? exp)
  176. (and (pair? exp)
  177. (eq? (car exp) 'unquote)))
  178. (define (datum? x)
  179. (or (boolean? x)
  180. (number? x)
  181. (string? x)
  182. (char? x)))
  183. (define (do-qq l)
  184. (if (or (null? l) (symbol? l))
  185. (list2 'quote l)
  186. (if (datum? l)
  187. l
  188. (if (unquote? l)
  189. (cadr l)
  190. (list3 'cons
  191. (do-qq (car l))
  192. (do-qq (cdr l)))))))
  193. (defmacro quasiquote
  194. (lambda (exp)
  195. (do-qq (cadr exp))))
  196. ;;; COND SHAPE PREDICATES
  197. ;;; AND EXTRACTORS
  198. (define (cond/0? exp)
  199. ;; (cond)
  200. (and (pair? exp) (eq? 'cond (car exp)) (null? (cdr exp))))
  201. (define (cond/else? exp)
  202. ;; (cond (else . <rest>))
  203. (and (pair? exp) (eq? 'cond (car exp)) (pair? (cdr exp))
  204. (pair? (cadr exp)) (eq? 'else (car (cadr exp)))))
  205. (define (cond-get-else exp)
  206. `(begin . ,(cdr (cadr exp))))
  207. (define (cond/1? exp)
  208. ;; (cond (<one>) . <rest>)
  209. (and (pair? exp) (eq? 'cond (car exp)) (pair? (cdr exp))
  210. (pair? (cadr exp)) (not (eq? 'else (car (cadr exp))))
  211. (null? (cdr (cadr exp)))))
  212. (define (cond-get-1 exp)
  213. (car (cadr exp)))
  214. (define (cond/clause? exp)
  215. ;; (cond (<test> . <rest>) . <rest>)
  216. (and (pair? exp) (eq? 'cond (car exp)) (pair? (cdr exp))
  217. (pair? (cadr exp)) (not (eq? 'else (car (cadr exp))))))
  218. (define (cond/clause-get-test exp)
  219. (car (cadr exp)))
  220. (define (cond/clause-get-rest exp)
  221. `(begin . ,(cdr (cadr exp))))
  222. (define (cond/=>-clause? exp)
  223. ;; (cond (<test> => <thunk>) . <rest>)
  224. (and (pair? exp) (eq? 'cond (car exp)) (pair? (cdr exp))
  225. (pair? (cadr exp)) (not (eq? 'else (car (cadr exp))))
  226. (pair? (cdr (cadr exp))) (eq? '=> (cadr (cadr exp)))))
  227. (define (cond/=>-clause-get-thunk exp)
  228. (caddr (cadr exp)))
  229. (define (cond-get-next exp)
  230. `(cond . ,(cddr exp)))
  231. (defmacro cond
  232. (lambda (exp)
  233. (if (cond/0? exp)
  234. `(builtin exit) ;; todo void
  235. (if (cond/else? exp)
  236. (cond-get-else exp)
  237. (if (cond/1? exp)
  238. `(or ,(cond-get-1 exp) ,(cond-get-next exp))
  239. (if (cond/=>-clause? exp)
  240. (let ((test (cond/clause-get-test exp))
  241. (thunk (cond/=>-clause-get-thunk exp))
  242. (tmp (gensym 'cond-tmp)))
  243. `(let ((,tmp ,test))
  244. (if ,tmp
  245. (,thunk ,tmp)
  246. ,(cond-get-next exp))))
  247. (if (cond/clause? exp)
  248. (let ((test (cond/clause-get-test exp))
  249. (rest (cond/clause-get-rest exp)))
  250. `(if ,test
  251. ,rest
  252. ,(cond-get-next exp)))
  253. (builtin exit) ;; bad syntax
  254. )))))))
  255. (defmacro when
  256. (lambda (exp)
  257. (let ((test (cadr exp))
  258. (body `(begin . ,(cddr exp))))
  259. `(if ,test
  260. ,body
  261. #f))))
  262. (defmacro unless
  263. (lambda (exp)
  264. (let ((test (cadr exp))
  265. (body `(begin . ,(cddr exp))))
  266. `(if ,test
  267. #f
  268. ,body))))
  269. ;; <case> ::= (case <exp> <clause> (else <exp>))
  270. ;;
  271. ;; <clause> ::= ((<thing>) <exp>)
  272. ;; (case foo ((x) 1) ((y) 2) (else 3))
  273. ;; -->
  274. ;; let tmp foo
  275. ;; (if (eq? tmp 'x) 1)
  276. ;; ...((y) 2) (else 3))
  277. (define (else-clause? head)
  278. (and (pair? head)
  279. (eq? 'else (car head))))
  280. (define (compile-case t clauses)
  281. (if (null? clauses)
  282. '(builtin exit)
  283. (let ((head (car clauses))
  284. (rest (cdr clauses)))
  285. (if (else-clause? head)
  286. (cadr head)
  287. (let ((test (caar head))
  288. (body (cdr head)))
  289. `(if (eq? ,t ',test)
  290. (begin . ,body)
  291. ,(compile-case t rest)))))))
  292. (defmacro case
  293. (lambda (exp)
  294. (let ((discriminant (cadr exp))
  295. (tmp (gensym 'tmp)))
  296. `(let ((,tmp ,discriminant))
  297. ,(compile-case tmp (cddr exp))))))
  298. ; MAGIC> (include "runtime/macro-case.scm")
  299. ; MAGIC> (case (+ 1 1) ((1) 'one) ((2) 'two) (else 'dunno))
  300. ; two
  301. (defmacro vector
  302. (lambda (exp)
  303. (let ((l (length (cdr exp)))
  304. (tmp (gensym "tmp")))
  305. (letrec ((loop (lambda (i elts)
  306. (if (null? elts)
  307. tmp
  308. `(begin
  309. (vector-set! ,tmp ,i ,(car elts))
  310. ,(loop (+ i 1) (cdr elts)))))))
  311. `(let ((,tmp (make-vector ,l #f)))
  312. ,(loop 0 (cdr exp)))))))
  313. (defmacro mapply
  314. (lambda (exp)
  315. ;;(mapply f xs arg ...)
  316. (let ((f (cadr exp))
  317. (xs (caddr exp))
  318. (args (cdddr exp))
  319. (x (gensym "x")))
  320. `(map (lambda (,x) (,f ,x . ,args)) ,xs))))
  321. (defmacro list
  322. (lambda (exp)
  323. (let loop ((xs (cdr exp)))
  324. (if (null? xs)
  325. ''()
  326. `(cons ,(car xs) ,(loop (cdr xs)))))))
  327. (define (bind-assocs tmp vars body)
  328. (if (null? vars)
  329. body
  330. `(let ((,(car vars) (cdr (assoc ',(car vars) ,tmp))))
  331. ,(bind-assocs tmp (cdr vars) body))))
  332. (defmacro match-assoc
  333. (lambda (exp)
  334. (let ((thing (cadr exp))
  335. (vars (caddr exp))
  336. (body `(begin . ,(cdddr exp)))
  337. (tmp (gensym "tmp")))
  338. `(let ((,tmp ,thing))
  339. ,(bind-assocs tmp vars body)))))
  340. (define (assoc-replace tbl key val)
  341. (if (null? tbl)
  342. (cons (cons key val) '())
  343. (let ((entry (car tbl)))
  344. (if (eq? (car entry) key)
  345. (cons (cons key val) (cdr tbl))
  346. (cons entry (assoc-replace (cdr tbl) key val))))))
  347. (define (assoc-update tbl key f default)
  348. (if (null? tbl)
  349. (cons (cons key default) '())
  350. (let ((entry (car tbl)))
  351. (if (eq? (car entry) key)
  352. (cons (cons key (f (cdr entry))) (cdr tbl))
  353. (cons entry (assoc-update (cdr tbl) key f default))))))
  354. (define (assoc-split table keys k)
  355. (let loop ((left '()) (right '()) (table table))
  356. (if (null? table)
  357. (k left right)
  358. (let ((entry (car table)))
  359. (if (member (car entry) keys)
  360. (loop (cons entry left) right (cdr table))
  361. (loop left (cons entry right) (cdr table)))))))
  362. (defmacro transform-assoc
  363. (lambda (exp)
  364. (let ((thing (cadr exp))
  365. (vars (caddr exp))
  366. (body `(begin . ,(cdddr exp)))
  367. (tmp (gensym "tmp"))
  368. (in (gensym "in"))
  369. (out (gensym "out")))
  370. `(let ((,tmp ,thing))
  371. (assoc-split ,tmp ',vars
  372. (lambda (,in ,out)
  373. (append (match-assoc ,in ,vars ,body) ,out)))))))
  374. (define (display-symbol form) (display form))
  375. (define (display-char ch) (display ch))
  376. (define (display-chars ch) (for-each display-char ch))
  377. (define (display-boolean form)
  378. (if form
  379. (display-chars '(#\# #\t))
  380. (display-chars '(#\# #\f))))
  381. (define (display-int form) (display form))
  382. (define (vector->list v)
  383. (let ((l (vector-length v)))
  384. (let loop ((i 0))
  385. (if (= i l)
  386. '()
  387. (cons (vector-ref v i)
  388. (loop (+ i 1)))))))
  389. (define (my-display form)
  390. (cond ((symbol? form) (display-symbol form))
  391. ((string? form)
  392. (display-char #\")
  393. (display form) ;; TODO escaping
  394. (display-char #\"))
  395. ((char? form) (display-char form))
  396. ((boolean? form) (display-boolean form))
  397. ((number? form) (display-int form))
  398. ((null? form) (display-chars '(#\( #\))))
  399. ((vector? form)
  400. (display-char #\#)
  401. (my-display (vector->list form)))
  402. ((pair? form)
  403. (display-char #\()
  404. (let loop ((form form))
  405. (my-display (car form))
  406. (cond ((null? (cdr form))
  407. (display-char #\)))
  408. ((pair? (cdr form))
  409. (display-char #\space)
  410. (loop (cdr form)))
  411. (else (display-chars '(#\space #\. #\space))
  412. (my-display (cdr form))
  413. (display-char #\))))))
  414. (else
  415. (display "[????]"))))
  416. (define (print p) (my-display p) (newline))
  417. (define (length=? l n)
  418. ;; tests if a list has a certain length
  419. ;; failing early if possible
  420. ;; failing on non-lists
  421. (let loop ((l l) (n n))
  422. (cond ((< n 0) #f)
  423. ((null? l) (= n 0))
  424. ((pair? l) (loop (cdr l) (- n 1)))
  425. (else #f))))
  426. (define (length>=? l n)
  427. (let loop ((l l) (n n))
  428. (cond ((< n 0) #f)
  429. ((= n 0) #t)
  430. ((null? l) #f)
  431. ((pair? l) (loop (cdr l) (- n 1)))
  432. (else #f))))
  433. (define (extend! b v)
  434. ;; b is a box containing a mutable list
  435. ;; v is the element you want added on to the end
  436. ;; returns the length after extending
  437. ;;
  438. (if (null? (unbox b))
  439. (begin (set-box! b (cons v '())) 1)
  440. (let loop ((pair (unbox b)) (i 2))
  441. (if (null? (cdr pair))
  442. (begin (set-cdr! pair (cons v '())) i)
  443. (loop (cdr pair) (+ i 1))))))
  444. (define (index obj lst)
  445. (let loop ((lst lst) (i 0))
  446. (if (null? lst)
  447. #f
  448. (if (equal? obj (car lst))
  449. i
  450. (loop (cdr lst) (+ i 1))))))
  451. (define (reverse-index obj lst)
  452. (let loop ((lst (reverse lst)) (i (- (length lst) 1)))
  453. (if (null? lst)
  454. #f
  455. (if (equal? obj (car lst))
  456. i
  457. (loop (cdr lst) (- i 1))))))
  458. (define (copy-list l)
  459. (if (null? l)
  460. '()
  461. (cons (car l) (copy-list (cdr l)))))
  462. (define map* map)
  463. (define (vector-for-each proc vec)
  464. (let ((len (vector-length vec)))
  465. (let loop ((i 0))
  466. (unless (= i len)
  467. (proc (vector-ref vec i))
  468. (loop (+ i 1))))))
  469. (define (vector-grow vec extra fill)
  470. ;; (vector-grow (vector 'a 'b 'c) 2 #f)
  471. ;; ;=> #(a b c #f #f)
  472. ;;
  473. (let ((res (make-vector (+ (vector-length vec) extra) fill)))
  474. (let ((i (box 0)))
  475. (vector-for-each
  476. (lambda (elt)
  477. (vector-set! res (unbox i) elt)
  478. (set-box! i (+ (unbox i) 1)))
  479. vec))
  480. res))
  481. (define (vector-append vec-1 vec-2)
  482. (let ((res (vector-grow vec-1 (vector-length vec-2) #f)))
  483. (let ((i (box (vector-length vec-1))))
  484. (vector-for-each
  485. (lambda (elt)
  486. (vector-set! res (unbox i) elt)
  487. (set-box! i (+ (unbox i) 1)))
  488. vec-2))
  489. res))
  490. (define (vector-overlay! vec-1 start vec-2)
  491. (let ((i (box start)))
  492. (vector-for-each (lambda (elt)
  493. (vector-set! vec-1 (unbox i) elt)
  494. (set-box! i (+ (unbox i) 1)))
  495. vec-2))
  496. #t)
  497. (define (list->vector l)
  498. (let ((len (length l)))
  499. (let ((vec (make-vector len #f)))
  500. (let loop ((i 0) (l l))
  501. (if (null? l)
  502. vec
  503. (begin (vector-set! vec i (car l))
  504. (loop (+ i 1) (cdr l))))))))
  505. ; (match <expr>
  506. ; (<pattern> <expr>)
  507. ; (<pattern> <expr>)
  508. ; ...)
  509. ; pattern ::= number? | symbol? | '<expr> | (<pattern> . <pattern>)
  510. (define (moo-match e)
  511. (let ((exp (cadr e))
  512. (clauses (cddr e))
  513. (tmp (gensym "tmp")))
  514. `(let ((,tmp ,exp))
  515. ,(moo-match-aux tmp clauses))))
  516. (define (quote? p)
  517. (and (pair? p) (eq? (car p) 'quote)))
  518. ; takes: expression to match on, pattern, body, place, failure continuation
  519. ; returns: code that returns #t if pattern matches and #f if not, and an assoc list of
  520. ; bindings
  521. (define (subpattern-match s p)
  522. (begin ;(print `("in subpatterN" ,s ,p))
  523. (cond
  524. ((null? p)
  525. (cons `((null? ,s))
  526. '()))
  527. ((number? p)
  528. (cons `((number? ,s) (= ,s ,p))
  529. '()))
  530. ((symbol? p)
  531. (cons `(#t)
  532. `((,p ,s))))
  533. ((quote? p)
  534. (cons `((equal? ',(cadr p) ,s))
  535. '()))
  536. ((pair? p)
  537. (let ((l (subpattern-match `(car ,s) (car p)))
  538. (r (subpattern-match `(cdr ,s) (cdr p))))
  539. (cons (cons `(pair? ,s) (append (car l) (car r)))
  540. (append (cdr l) (cdr r)))))
  541. (else
  542. (begin
  543. (print "undefined subpattern")
  544. (print p))))))
  545. (define (try t pat body fk)
  546. (let ((m (subpattern-match t pat)))
  547. `(if (and . ,(car m))
  548. ,(if (not (null? (cdr m)))
  549. `(let ,(cdr m)
  550. ,body)
  551. body)
  552. (,fk))))
  553. (define (moo-match-aux t clauses)
  554. (if (null? clauses)
  555. `(error 'match "match fail")
  556. (let ((pat (caar clauses))
  557. (body `(begin . ,(cdar clauses)))
  558. (fk (gensym "fk")))
  559. `(let ((,fk (lambda ()
  560. ,(moo-match-aux t (cdr clauses)))))
  561. ,(try t pat body fk)))))
  562. (defmacro match moo-match)
  563. (define (datum? exp) (or (boolean? exp) (number? exp) (char? exp) (string? exp)))
  564. (define (quote? exp) (and (length=? exp 2) (eq? 'quote (car exp))))
  565. (define variable? symbol?)
  566. (define (if? exp) (and (length=? exp 4) (eq? 'if (car exp))))
  567. (define (begin? exp) (and (pair? exp) (eq? 'begin (car exp))))
  568. (define (lambda? exp) (and (length>=? exp 3) (eq? 'lambda (car exp))))
  569. (define (named-let? exp) (and (length>=? exp 4) (eq? 'let (car exp)) (symbol? (cadr exp))))
  570. (define (let? exp) (and (length>=? exp 3) (eq? 'let (car exp))))
  571. (define (letrec? exp) (and (length=? exp 3) (eq? 'letrec (car exp))))
  572. (define (builtin-app? e) (and (pair? e) (eq? 'builtin (car e))))
  573. (define app? pair?)
  574. ;; Sequence grammar:
  575. ;; <s> ::= nil
  576. ;; | (join <s> <s>)
  577. ;; | (cat [list of <s>])
  578. ;; | (elt <element>)
  579. (define (foldr f z l)
  580. (if (null? l)
  581. z
  582. (f (car l) (foldr f z (cdr l)))))
  583. (define (sequence->dlist s rest)
  584. (match s
  585. ('nil rest)
  586. (('join x y) (sequence->dlist x (sequence->dlist y rest)))
  587. (('cat seqs) (foldr sequence->dlist rest seqs))
  588. (('elt x) (cons x rest))
  589. (else (error 'sequence->dlist "invalid sequence" s))))
  590. (define (sequence->list s)
  591. (sequence->dlist s '()))
  592. (define (box val) (make-vector 1 val))
  593. (define (unbox b) (vector-ref b 0))
  594. (define (set-box! b v) (vector-set! b 0 v))