node.scm 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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
  6. ;;;
  7. ;;; scheme48-1.9.2/scheme/bcomp/node.scm
  8. (define-module (prescheme bcomp node)
  9. #:use-module (srfi srfi-9)
  10. #:use-module (prescheme scheme48)
  11. #:use-module (prescheme bcomp mtype)
  12. #:use-module (prescheme record-discloser)
  13. #:export (make-node
  14. node?
  15. node-operator
  16. node-operator-id
  17. node-form
  18. node-ref
  19. node-set!
  20. node-predicate
  21. make-similar-node
  22. force-node
  23. name->qualified
  24. get-operator
  25. make-operator-table
  26. operator-name
  27. operator-nargs
  28. operator-table-ref
  29. operator-define!
  30. operator-lookup
  31. operator-type
  32. operator-uid
  33. operator?
  34. operators-table ;;config.scm comp-package.scm
  35. lambda-node?
  36. flat-lambda-node?
  37. name-node?
  38. call-node?
  39. literal-node?
  40. quote-node?
  41. define-node?
  42. loophole-node?
  43. operator/flat-lambda
  44. operator/lambda
  45. operator/set!
  46. operator/call
  47. operator/begin
  48. operator/name
  49. operator/letrec
  50. operator/letrec*
  51. operator/pure-letrec
  52. operator/literal
  53. operator/quote
  54. operator/unassigned
  55. operator/unspecific
  56. operator/define
  57. operator/define-syntax
  58. operator/primitive-procedure
  59. operator/structure-ref))
  60. ;; --------------------
  61. ;; Operators (= special operators and primitives)
  62. (define-record-type :operator
  63. (make-operator type nargs uid name)
  64. operator?
  65. (type operator-type set-operator-type!)
  66. (nargs operator-nargs)
  67. (uid operator-uid)
  68. (name operator-name))
  69. (define-record-discloser :operator
  70. (lambda (s)
  71. (list 'operator
  72. (operator-name s)
  73. (if (symbol? (operator-type s))
  74. (operator-type s)
  75. (type->sexp (operator-type s) #t)))))
  76. (define usual-operator-type
  77. (procedure-type any-arguments-type value-type #f))
  78. (define (get-operator name . type-option)
  79. (let ((type (if (null? type-option) #f (car type-option)))
  80. (probe (table-ref operators-table name)))
  81. (if (operator? probe)
  82. (let ((previous-type (operator-type probe)))
  83. (cond ((not type))
  84. ((not previous-type)
  85. (set-operator-type! probe type))
  86. ((symbol? type) ;; 'leaf or 'internal
  87. (if (not (eq? type previous-type))
  88. (warning 'get-operator
  89. "operator type inconsistency" name type previous-type)))
  90. ((subtype? type previous-type) ;;Improvement
  91. (set-operator-type! probe type))
  92. ((not (subtype? previous-type type))
  93. (warning 'get-operator
  94. "operator type inconsistency"
  95. name
  96. (type->sexp previous-type 'foo)
  97. (type->sexp type 'foo))))
  98. probe)
  99. (let* ((uid *operator-uid*)
  100. (op (make-operator type
  101. (if (and type
  102. (not (symbol? type))
  103. (fixed-arity-procedure-type? type))
  104. (procedure-type-arity type)
  105. #f)
  106. uid
  107. name)))
  108. (if (>= uid number-of-operators)
  109. (warning 'get-operator
  110. "too many operators" (operator-name op) (operator-type op)))
  111. (set! *operator-uid* (+ *operator-uid* 1))
  112. (table-set! operators-table (operator-name op) op)
  113. (vector-set! the-operators uid op)
  114. op))))
  115. (define *operator-uid* 0)
  116. (define operators-table (make-table))
  117. (define number-of-operators 400) ;;Fixed-size limits bad, but speed good
  118. (define the-operators (make-vector number-of-operators #f))
  119. ;; --------------------
  120. ;; Operator tables (for fast dispatch)
  121. (define (make-operator-table default)
  122. (make-vector number-of-operators default))
  123. (define operator-table-ref vector-ref)
  124. (define (operator-lookup table op)
  125. (operator-table-ref table (operator-uid op)))
  126. (define (operator-define! table name type proc)
  127. (vector-set! table
  128. (operator-uid (get-operator name type))
  129. proc))
  130. ;; --------------------
  131. ;; Nodes
  132. ;; A node is an annotated expression (or definition or other form).
  133. ;; The FORM component of a node is an S-expression of the same form as
  134. ;; the S-expression representation of the expression. E.g. for
  135. ;; literals, the form is the literal value; for variables the form is
  136. ;; the variable name; for IF expressions the form is a 4-element list
  137. ;; (<if> test con alt). Nodes also have a tag identifying what kind
  138. ;; of node it is (literal, variable, if, etc.) and a property list.
  139. (define-record-type :node
  140. (really-make-node uid form plist)
  141. node?
  142. (uid node-operator-id)
  143. (form node-form)
  144. (plist node-plist set-node-plist!))
  145. (define-record-discloser :node
  146. (lambda (n) (list (operator-name (node-operator n)) (node-form n))))
  147. (define (make-node operator form)
  148. (really-make-node (operator-uid operator) form '()))
  149. (define (node-ref node key)
  150. (let ((probe (assq key (node-plist node))))
  151. (if probe (cdr probe) #f)))
  152. ;; removes property if value is #f
  153. (define (node-set! node key value) ;;gross
  154. (if value
  155. (let ((probe (assq key (node-plist node))))
  156. (if probe
  157. (set-cdr! probe value)
  158. (set-node-plist! node (cons (cons key value) (node-plist node)))))
  159. (let loop ((l (node-plist node)) (prev #f))
  160. (cond ((null? l) 'lose)
  161. ((eq? key (caar l))
  162. (if prev
  163. (set-cdr! prev (cdr l))
  164. (set-node-plist! node (cdr l))))
  165. (else (loop (cdr l) l))))))
  166. (define (node-operator node)
  167. (vector-ref the-operators (node-operator-id node)))
  168. (define (node-predicate name . type-option)
  169. (let ((id (operator-uid (apply get-operator name type-option))))
  170. (lambda (node)
  171. (= (node-operator-id node) id))))
  172. (define (make-similar-node node form)
  173. (if (equal? form (node-form node))
  174. node
  175. (make-node (node-operator node) form)))
  176. ;; Top-level nodes are often delayed.
  177. (define (force-node node)
  178. (if (node? node)
  179. node
  180. (force node)))
  181. ;; Node predicates and operators.
  182. (define lambda-node? (node-predicate 'lambda syntax-type))
  183. (define flat-lambda-node? (node-predicate 'flat-lambda syntax-type))
  184. (define call-node? (node-predicate 'call))
  185. (define name-node? (node-predicate 'name 'leaf))
  186. (define literal-node? (node-predicate 'literal 'leaf))
  187. (define quote-node? (node-predicate 'quote syntax-type))
  188. (define define-node? (node-predicate 'define))
  189. (define loophole-node? (node-predicate 'loophole))
  190. (define operator/flat-lambda (get-operator 'flat-lambda))
  191. (define operator/lambda (get-operator 'lambda syntax-type))
  192. (define operator/set! (get-operator 'set! syntax-type))
  193. (define operator/call (get-operator 'call 'internal))
  194. (define operator/begin (get-operator 'begin syntax-type))
  195. (define operator/name (get-operator 'name 'leaf))
  196. (define operator/letrec (get-operator 'letrec))
  197. (define operator/letrec* (get-operator 'letrec*))
  198. (define operator/pure-letrec (get-operator 'pure-letrec))
  199. (define operator/literal (get-operator 'literal))
  200. (define operator/quote (get-operator 'quote syntax-type))
  201. (define operator/unassigned (get-operator 'unassigned))
  202. (define operator/unspecific (get-operator 'unspecific (proc () unspecific-type)))
  203. (define operator/define (get-operator 'define syntax-type))
  204. (define operator/define-syntax (get-operator 'define-syntax syntax-type))
  205. (define operator/primitive-procedure
  206. (get-operator 'primitive-procedure syntax-type))
  207. (define operator/structure-ref (get-operator 'structure-ref syntax-type))