syntax.scm 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom
  6. ;;;
  7. ;;; scheme48-1.9.2/scheme/bcomp/syntax.scm
  8. ;;;
  9. ;;; Macro expansion.
  10. ;;;
  11. ;;;----------------
  12. ;;; Scanning for definitions.
  13. ;;;
  14. ;;; Returns a list of forms expanded to the point needed to distinguish
  15. ;;; definitions from other forms. Definitions and syntax definitions are
  16. ;;; added to ENV.
  17. (define-module (prescheme bcomp syntax)
  18. #:use-module (prescheme scheme48)
  19. #:use-module (prescheme bcomp binding)
  20. #:use-module (prescheme bcomp cenv)
  21. #:use-module (prescheme bcomp mtype)
  22. #:use-module (prescheme bcomp name)
  23. #:use-module (prescheme bcomp node)
  24. #:use-module (prescheme bcomp schemify)
  25. #:use-module (prescheme bcomp transform)
  26. #:export (expand
  27. expand-form
  28. scan-forms
  29. expand-scanned-form
  30. syntax?
  31. static-value))
  32. (define (scan-forms forms env)
  33. (let loop ((forms forms) (expanded '()))
  34. (if (null? forms)
  35. (reverse expanded)
  36. (let ((form (expand-head (car forms) env))
  37. (more-forms (cdr forms)))
  38. (cond ((define? form)
  39. (loop more-forms
  40. (cons (scan-define form env) expanded)))
  41. ((define-syntax? form)
  42. (loop more-forms
  43. (append (scan-define-syntax form env)
  44. expanded)))
  45. ((begin? form)
  46. (loop (append (cdr form) more-forms)
  47. expanded))
  48. (else
  49. (loop more-forms (cons form expanded))))))))
  50. (define (expand-scanned-form form env)
  51. (if (define? form)
  52. (expand-define form env)
  53. (expand form env)))
  54. (define (scan-define form env)
  55. (let ((new-form (destructure-define form)))
  56. (if new-form
  57. (begin
  58. (comp-env-define! env (cadr new-form) usual-variable-type)
  59. new-form)
  60. (syntax-violation 'syntax-rules "ill-formed definition" form))))
  61. (define (expand-define form env)
  62. (make-node operator/define
  63. (list (car form)
  64. (expand (cadr form) env)
  65. (expand (caddr form) env))))
  66. (define (scan-define-syntax form env)
  67. (if (and (or (this-long? form 3)
  68. (this-long? form 4)) ;; may have name list for reifier
  69. (name? (cadr form)))
  70. (let ((name (cadr form))
  71. (source (caddr form))
  72. (package (extract-package-from-comp-env env)))
  73. (comp-env-define! env
  74. name
  75. syntax-type
  76. (process-syntax (if (null? (cdddr form))
  77. source
  78. `(cons ,source ',(cadddr form)))
  79. env
  80. name
  81. package))
  82. '())
  83. (syntax-violation 'define-syntax "ill-formed syntax definition" form)))
  84. ;; This is used by the ,expand command.
  85. (define (expand-form form env)
  86. (let loop ((forms (list form)) (expanded '()))
  87. (if (null? forms)
  88. (if (= (length expanded) 1)
  89. (car expanded)
  90. (make-node operator/begin (cons 'begin (reverse expanded))))
  91. (let ((form (expand-head (car forms) env))
  92. (more-forms (cdr forms)))
  93. (cond ((define? form)
  94. (let* ((new-form (destructure-define form))
  95. (temp (if new-form
  96. (expand-define new-form env)
  97. (syntax-violation 'expand "ill-formed definition"
  98. form))))
  99. (loop more-forms (cons temp expanded))))
  100. ((define-syntax? form)
  101. (loop more-forms
  102. (cons (make-node operator/define-syntax
  103. (list (car form)
  104. (expand (cadr form) env)
  105. (make-node operator/quote
  106. `',(caddr form))))
  107. expanded)))
  108. ((begin? form)
  109. (loop (append (cdr form) more-forms)
  110. expanded))
  111. (else
  112. (loop more-forms
  113. (cons (expand form env) expanded))))))))
  114. ;;----------------
  115. ;; Looking for definitions.
  116. ;; This expands the form until it reaches a name, a form whose car is an
  117. ;; operator, a form whose car is unknown, or a literal.
  118. (define (expand-head form env)
  119. (cond ((node? form)
  120. (if (and (name-node? form)
  121. (not (node-ref form 'binding)))
  122. (expand-name (node-form form) env)
  123. form))
  124. ((name? form)
  125. (expand-name form env))
  126. ((pair? form)
  127. (let ((op (expand-head (car form) env)))
  128. (if (and (node? op)
  129. (name-node? op))
  130. (let ((probe (node-ref op 'binding)))
  131. (if (binding? probe)
  132. (let ((s (binding-static probe)))
  133. (cond ((and (transform? s)
  134. (eq? (binding-type probe) syntax-type))
  135. (expand-macro-application
  136. s (cons op (cdr form)) env expand-head))
  137. ((and (operator? s)
  138. (eq? s operator/structure-ref))
  139. (expand-structure-ref form env expand-head))
  140. (else
  141. (cons op (cdr form)))))
  142. (cons op (cdr form))))
  143. (cons op (cdr form)))))
  144. (else
  145. form)))
  146. ;; Returns a DEFINE of the form (define <id> <value>). This handles the following
  147. ;; kinds of defines:
  148. ;; (define <id> <value>)
  149. ;; (define <id>) ;; value is unassigned
  150. ;; (define (<id> . <formals>) <value>) ;; value is a lambda
  151. ;; The return value is #f if any syntax error is found.
  152. (define (destructure-define form)
  153. (if (at-least-this-long? form 2)
  154. (let ((pat (cadr form))
  155. (operator (car form)))
  156. (cond ((pair? pat)
  157. (if (and (name? (car pat))
  158. (names? (cdr pat))
  159. (not (null? (cddr form))))
  160. `(,operator ,(car pat)
  161. (,operator/lambda ,(cdr pat)
  162. . ,(cddr form)))
  163. #f))
  164. ((null? (cddr form))
  165. `(,operator ,pat (,operator/unassigned)))
  166. ((null? (cdddr form))
  167. `(,operator ,pat ,(caddr form)))
  168. (else
  169. #f)))
  170. #f))
  171. (define (make-operator-predicate operator-id)
  172. (let ((operator (get-operator operator-id syntax-type)))
  173. (lambda (form)
  174. (and (pair? form)
  175. (eq? operator
  176. (static-value (car form)))))))
  177. (define define? (make-operator-predicate 'define))
  178. (define begin? (make-operator-predicate 'begin))
  179. (define define-syntax? (make-operator-predicate 'define-syntax))
  180. (define (static-value form)
  181. (if (and (node? form)
  182. (name-node? form))
  183. (let ((probe (node-ref form 'binding)))
  184. (if (binding? probe)
  185. (binding-static probe)
  186. #f))
  187. #f))
  188. ;; --------------------
  189. ;; The horror of internal defines
  190. ;; This returns a single node, either a LETREC, if there are internal definitions,
  191. ;; or a BEGIN if there aren't any. If there are no expressions we turn the last
  192. ;; definition back into an expression, thus causing the correct warning to be
  193. ;; printed by the compiler.
  194. (define (expand-body body env)
  195. (if (null? (cdr body)) ;++
  196. (expand (car body) env)
  197. (call-with-values
  198. (lambda ()
  199. (scan-body-forms body env '()))
  200. (lambda (defs exps env)
  201. (if (null? defs)
  202. (make-node operator/begin (cons 'begin (expand-list exps env)))
  203. (call-with-values
  204. (lambda ()
  205. (if (null? exps)
  206. (values (reverse (cdr defs))
  207. `((,operator/define ,(caar defs) ,(cdar defs))))
  208. (values (reverse defs)
  209. exps)))
  210. (lambda (defs exps)
  211. (expand-letrec operator/letrec
  212. (map car defs)
  213. (map cdr defs)
  214. exps
  215. env))))))))
  216. ;; Walk through FORMS looking for definitions. ENV is the current environment,
  217. ;; DEFS a list of definitions found so far.
  218. ;;
  219. ;; Returns three values: a list of (define <name> <value>) lists, a list of
  220. ;; remaining forms, and the environment to use for expanding all of the above.
  221. (define (scan-body-forms forms env defs)
  222. (if (null? forms)
  223. (values defs '() env)
  224. (let ((form (expand-head (car forms) env))
  225. (more-forms (cdr forms)))
  226. (cond ((define? form)
  227. (let ((new-form (destructure-define form)))
  228. (if new-form
  229. (let* ((name (cadr new-form))
  230. (node (make-node operator/name name)))
  231. (scan-body-forms more-forms
  232. (bind1 name node env)
  233. (cons (cons node
  234. (caddr new-form))
  235. defs)))
  236. (syntax-violation 'scan-body-forms
  237. "ill-formed definition" form))))
  238. ((begin? form)
  239. (call-with-values
  240. (lambda ()
  241. (scan-body-forms (cdr form)
  242. env
  243. defs))
  244. (lambda (new-defs exps env)
  245. (cond ((null? exps)
  246. (scan-body-forms more-forms env new-defs))
  247. ((eq? new-defs defs)
  248. (values defs (append exps more-forms) env))
  249. (else
  250. (body-lossage forms env))))))
  251. (else
  252. (values defs (cons form more-forms) env))))))
  253. (define (body-lossage node env)
  254. (syntax-violation 'body
  255. "definitions and expressions intermixed"
  256. (schemify node env)))
  257. ;;--------------------
  258. ;; Expands all macros in FORM and returns a node.
  259. (define (expand form env)
  260. (cond ((node? form)
  261. (if (and (name-node? form)
  262. (not (node-ref form 'binding)))
  263. (expand-name (node-form form) env)
  264. form))
  265. ((name? form)
  266. (expand-name form env))
  267. ((pair? form)
  268. (if (operator? (car form))
  269. (expand-operator-form (car form) (car form) form env)
  270. (let ((op-node (expand (car form) env)))
  271. (if (name-node? op-node)
  272. (let ((probe (node-ref op-node 'binding)))
  273. (if (binding? probe)
  274. (let ((s (binding-static probe)))
  275. (cond ((operator? s)
  276. (expand-operator-form s op-node form env))
  277. ((and (transform? s)
  278. (eq? (binding-type probe) syntax-type))
  279. ;; Non-syntax transforms get done later
  280. (expand-macro-application
  281. s (cons op-node (cdr form)) env expand))
  282. (else
  283. (expand-call op-node form env))))
  284. (expand-call op-node form env)))
  285. (expand-call op-node form env)))))
  286. ((literal? form)
  287. (expand-literal form))
  288. ;; ((qualified? form) ...)
  289. (else
  290. (syntax-violation 'expand "invalid expression" form))))
  291. (define (expand-list exps env)
  292. (map (lambda (exp)
  293. (expand exp env))
  294. exps))
  295. (define (expand-literal exp)
  296. (make-node operator/literal (make-immutable! exp)))
  297. (define (expand-call proc-node exp env)
  298. (if (list? exp)
  299. (make-node operator/call
  300. (cons proc-node (expand-list (cdr exp) env)))
  301. (syntax-violation 'expand-call "invalid expression" exp)))
  302. ;; An environment is a procedure that takes a name and returns one of
  303. ;; the following:
  304. ;;
  305. ;; 1. A binding record.
  306. ;; 2. A pair (<binding-record> . <path>)
  307. ;; 3. A node, which is taken to be a substitution for the name.
  308. ;; Or, for lexically bound variables, this is just a name node.
  309. ;; 4. #f, for unbound variables
  310. ;;
  311. ;; In case 1, EXPAND caches the binding as the node's BINDING property.
  312. ;; In case 2, it simply returns the node.
  313. (define (expand-name name env)
  314. (let ((binding (lookup env name)))
  315. (if (node? binding)
  316. binding
  317. (let ((node (make-node operator/name name)))
  318. (node-set! node 'binding (or binding 'unbound))
  319. node))))
  320. ;; Expand a macro. EXPAND may either be expand or expand-head.
  321. (define (expand-macro-application transform form env-of-use expand)
  322. (call-with-values
  323. (lambda ()
  324. (maybe-apply-macro-transform transform
  325. form
  326. (node-form (car form))
  327. env-of-use))
  328. (lambda (new-form new-env)
  329. (if (eq? new-form form)
  330. (syntax-violation (schemify (car form) env-of-use)
  331. "use of macro doesn't match definition"
  332. (cons (schemify (car form) env-of-use)
  333. (desyntaxify (cdr form))))
  334. (expand new-form new-env)))))
  335. ;;--------------------
  336. ;; Specialist classifiers for particular operators
  337. (define (expand-operator-form op op-node form env)
  338. ((operator-table-ref expanders (operator-uid op))
  339. op op-node form env))
  340. (define expanders
  341. (make-operator-table (lambda (op op-node form env)
  342. (if (let ((nargs (operator-nargs op)))
  343. (or (not nargs)
  344. (and (list? (cdr form))
  345. (= nargs (length (cdr form))))))
  346. (make-node op
  347. (cons op-node
  348. (expand-list (cdr form) env)))
  349. (expand-call op-node form env)))))
  350. (define (define-expander name proc)
  351. (operator-define! expanders name syntax-type proc))
  352. ;; Definitions are not expressions.
  353. (define-expander 'define
  354. (lambda (op op-node exp env)
  355. (syntax-violation 'define
  356. (if (destructure-define exp)
  357. "definition in expression context"
  358. "ill-formed definition")
  359. exp)))
  360. ;; Remove generated names from quotations.
  361. (define-expander 'quote
  362. (lambda (op op-node exp env)
  363. (if (this-long? exp 2)
  364. (make-node op (list op (desyntaxify (cadr exp))))
  365. (syntax-violation 'quote "invalid expression" exp))))
  366. ;; Don't evaluate, but don't remove generated names either. This is
  367. ;; used when writing macro-defining macros. Once we have avoided the
  368. ;; use of DESYNTAXIFY it is safe to replace this with regular QUOTE.
  369. (define-expander 'code-quote
  370. (lambda (op op-node exp env)
  371. (if (this-long? exp 2)
  372. (make-node operator/quote (list op (cadr exp)))
  373. (syntax-violation 'code-quote "invalid expression" exp))))
  374. ;; Convert one-armed IF to two-armed IF.
  375. (define-expander 'if
  376. (lambda (op op-node exp env)
  377. (cond ((this-long? exp 3)
  378. (make-node op
  379. (cons op
  380. (expand-list (append (cdr exp)
  381. (list (unspecific-node)))
  382. env))))
  383. ((this-long? exp 4)
  384. (make-node op
  385. (cons op (expand-list (cdr exp) env))))
  386. (else
  387. (syntax-violation 'if "invalid expression" exp)))))
  388. (define (unspecific-node)
  389. (make-node operator/unspecific '(unspecific)))
  390. ;; For the module system:
  391. (define-expander 'structure-ref
  392. (lambda (op op-node form env)
  393. (expand-structure-ref form env expand)))
  394. ;; This is also called by EXPAND-HEAD, which passes in a different expander.
  395. (define (expand-structure-ref form env expander)
  396. (let ((struct-node (expand (cadr form) env))
  397. (lose (lambda ()
  398. (syntax-violation 'structure-ref "invalid structure reference" form))))
  399. (if (and (this-long? form 3)
  400. (name? (caddr form))
  401. (name-node? struct-node))
  402. (let ((b (node-ref struct-node 'binding)))
  403. (if (and (binding? b)
  404. (binding-static b)) ;; (structure? ...)
  405. (expander (generate-name (desyntaxify (caddr form))
  406. (binding-static b)
  407. (node-form struct-node))
  408. env)
  409. (lose)))
  410. (lose))))
  411. ;; Scheme 48 internal special form principally for use by the
  412. ;; DEFINE-STRUCTURES macro.
  413. (define-expander '%file-name%
  414. (lambda (op op-node form env)
  415. (make-node operator/quote `',(source-file-name env))))
  416. ;; Checking the syntax of others special forms
  417. (define-expander 'lambda
  418. (lambda (op op-node exp env)
  419. (if (and (at-least-this-long? exp 3)
  420. (names? (cadr exp)))
  421. (expand-lambda (cadr exp) (cddr exp) env)
  422. (syntax-violation 'lambda "invalid expression" exp))))
  423. (define (expand-lambda names body env)
  424. (call-with-values
  425. (lambda ()
  426. (bind-names names env))
  427. (lambda (names env)
  428. (make-node operator/lambda
  429. (list 'lambda names (expand-body body env))))))
  430. (define (bind-names names env)
  431. (let loop ((names names) (nodes '()) (out-names '()))
  432. (cond ((null? names)
  433. (values (reverse nodes)
  434. (bind out-names nodes env)))
  435. ((name? names)
  436. (let ((last (make-node operator/name names)))
  437. (values (append (reverse nodes) last)
  438. (bind (cons names out-names) (cons last nodes) env))))
  439. (else
  440. (let ((node (make-node operator/name (car names))))
  441. (loop (cdr names) (cons node nodes) (cons (car names) out-names)))))))
  442. (define (names? l)
  443. (or (null? l)
  444. (name? l)
  445. (and (pair? l)
  446. (name? (car l))
  447. (names? (cdr l)))))
  448. (define-expander 'set!
  449. (lambda (op op-node exp env)
  450. (if (and (this-long? exp 3)
  451. (name? (cadr exp)))
  452. (make-node op (cons op (expand-list (cdr exp) env)))
  453. (syntax-violation 'set! "invalid expression" exp))))
  454. (define (letrec-expander op/letrec)
  455. (lambda (op op-node exp env)
  456. (if (and (at-least-this-long? exp 3)
  457. (let-specs? (cadr exp)))
  458. (let ((specs (cadr exp))
  459. (body (cddr exp)))
  460. (let* ((names (map (lambda (spec)
  461. (make-node operator/name (car spec)))
  462. specs))
  463. (env (bind (map car specs) names env)))
  464. (expand-letrec op/letrec names (map cadr specs) body env)))
  465. (syntax-violation 'letrec "invalid expression" exp))))
  466. (define-expander 'letrec
  467. (letrec-expander operator/letrec))
  468. (define-expander 'letrec*
  469. (letrec-expander operator/letrec*))
  470. (define (expand-letrec op/letrec names values body env)
  471. (let* ((new-specs (map (lambda (name value)
  472. (list name
  473. (expand value env)))
  474. names
  475. values)))
  476. (make-node op/letrec
  477. (list 'letrec new-specs (expand-body body env)))))
  478. (define-expander 'loophole
  479. (lambda (op op-node exp env)
  480. (if (this-long? exp 3)
  481. (make-node op (list op
  482. (sexp->type (desyntaxify (cadr exp)) #t)
  483. (expand (caddr exp) env)))
  484. (syntax-violation 'loophole "invalid expression" exp))))
  485. (define-expander 'let-syntax
  486. (lambda (op op-node exp env)
  487. (if (and (at-least-this-long? exp 3)
  488. (let-specs? (cadr exp)))
  489. (let ((specs (cadr exp)))
  490. (expand-body (cddr exp)
  491. (bind (map car specs)
  492. (map (lambda (spec)
  493. (make-binding syntax-type
  494. (list 'let-syntax)
  495. (process-syntax (cadr spec)
  496. env
  497. (car spec)
  498. env)))
  499. specs)
  500. env)))
  501. (syntax-violation 'let-syntax "invalid expression" exp))))
  502. (define-expander 'letrec-syntax
  503. (lambda (op op-node exp env)
  504. (if (and (at-least-this-long? exp 3)
  505. (let-specs? (cadr exp)))
  506. (let* ((specs (cadr exp))
  507. (bindings (map (lambda (spec)
  508. (make-binding syntax-type
  509. (list 'letrec-syntax)
  510. 'unassigned))
  511. specs))
  512. (new-env (bind (map car specs) bindings env)))
  513. (for-each (lambda (spec binding)
  514. (set-binding-static! binding
  515. (process-syntax (cadr spec)
  516. new-env
  517. (car spec)
  518. new-env)))
  519. specs bindings)
  520. (expand-body (cddr exp) new-env))
  521. (syntax-violation 'letrec-syntax "invalid expression" exp))))
  522. (define (process-syntax form env name env-or-package)
  523. (let ((eval+env (force (comp-env-macro-eval env))))
  524. (make-transform/macro ((car eval+env) form (cdr eval+env))
  525. env-or-package
  526. syntax-type
  527. form
  528. name)))
  529. ;; This just looks up the names that the LAP code will want and replaces them
  530. ;; with the appropriate node.
  531. ;;
  532. ;; (lap <id> (<free name> ...) <instruction> ...)
  533. (define-expander 'lap
  534. (lambda (op op-node exp env)
  535. (if (and (at-least-this-long? exp 4)
  536. (name? (cdr exp))
  537. (every name? (caddr exp)))
  538. (make-node op `(,op
  539. ,(desyntaxify (cadr exp))
  540. ,(map (lambda (name)
  541. (expand-name (cadr exp) env))
  542. (caddr exp))
  543. . ,(cdddr exp)))
  544. (syntax-violation 'lap "invalid expression" exp))))
  545. ;; --------------------
  546. ;; Syntax checking utilities
  547. (define (this-long? l n)
  548. (cond ((null? l)
  549. (= n 0))
  550. ((pair? l)
  551. (this-long? (cdr l) (- n 1)))
  552. (else
  553. #f)))
  554. (define (at-least-this-long? l n)
  555. (cond ((null? l)
  556. (<= n 0))
  557. ((pair? l)
  558. (at-least-this-long? (cdr l) (- n 1)))
  559. (else
  560. #f)))
  561. (define (let-specs? x)
  562. (or (null? x)
  563. (and (pair? x)
  564. (let ((s (car x)))
  565. (and (pair? s)
  566. (name? (car s))
  567. (pair? (cdr s))
  568. (null? (cddr s))))
  569. (let-specs? (cdr x)))))
  570. ;; --------------------
  571. ;; Utilities
  572. (define (literal? exp)
  573. (or (number? exp) (char? exp) (string? exp) (boolean? exp)
  574. (code-vector? exp)))
  575. (define (syntax? d)
  576. (cond ((operator? d)
  577. (eq? (operator-type d) syntax-type))
  578. ((transform? d)
  579. (eq? (transform-type d) syntax-type))
  580. (else #f)))