node.scm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; --------------------
  4. ; Operators (= special operators and primitives)
  5. (define-record-type operator :operator
  6. (make-operator type nargs uid name)
  7. operator?
  8. (type operator-type set-operator-type!)
  9. (nargs operator-nargs)
  10. (uid operator-uid)
  11. (name operator-name))
  12. (define-record-discloser :operator
  13. (lambda (s)
  14. (list 'operator
  15. (operator-name s)
  16. (if (symbol? (operator-type s))
  17. (operator-type s)
  18. (type->sexp (operator-type s) #t)))))
  19. (define usual-operator-type
  20. (procedure-type any-arguments-type value-type #f))
  21. (define (get-operator name . type-option)
  22. (let ((type (if (null? type-option) #f (car type-option)))
  23. (probe (table-ref operators-table name)))
  24. (if (operator? probe)
  25. (let ((previous-type (operator-type probe)))
  26. (cond ((not type))
  27. ((not previous-type)
  28. (set-operator-type! probe type))
  29. ((symbol? type) ; 'leaf or 'internal
  30. (if (not (eq? type previous-type))
  31. (warning 'get-operator
  32. "operator type inconsistency" name type previous-type)))
  33. ((subtype? type previous-type) ;Improvement
  34. (set-operator-type! probe type))
  35. ((not (subtype? previous-type type))
  36. (warning 'get-operator
  37. "operator type inconsistency"
  38. name
  39. (type->sexp previous-type 'foo)
  40. (type->sexp type 'foo))))
  41. probe)
  42. (let* ((uid *operator-uid*)
  43. (op (make-operator type
  44. (if (and type
  45. (not (symbol? type))
  46. (fixed-arity-procedure-type? type))
  47. (procedure-type-arity type)
  48. #f)
  49. uid
  50. name)))
  51. (if (>= uid number-of-operators)
  52. (warning 'get-operator
  53. "too many operators" (operator-name op) (operator-type op)))
  54. (set! *operator-uid* (+ *operator-uid* 1))
  55. (table-set! operators-table (operator-name op) op)
  56. (vector-set! the-operators uid op)
  57. op))))
  58. (define *operator-uid* 0)
  59. (define operators-table (make-table))
  60. (define number-of-operators 400) ;Fixed-size limits bad, but speed good
  61. (define the-operators (make-vector number-of-operators #f))
  62. ; --------------------
  63. ; Operator tables (for fast dispatch)
  64. (define (make-operator-table default)
  65. (make-vector number-of-operators default))
  66. (define operator-table-ref vector-ref)
  67. (define (operator-lookup table op)
  68. (operator-table-ref table (operator-uid op)))
  69. (define (operator-define! table name type proc)
  70. (vector-set! table
  71. (operator-uid (get-operator name type))
  72. proc))
  73. ; --------------------
  74. ; Nodes
  75. ; A node is an annotated expression (or definition or other form).
  76. ; The FORM component of a node is an S-expression of the same form as
  77. ; the S-expression representation of the expression. E.g. for
  78. ; literals, the form is the literal value; for variables the form is
  79. ; the variable name; for IF expressions the form is a 4-element list
  80. ; (<if> test con alt). Nodes also have a tag identifying what kind
  81. ; of node it is (literal, variable, if, etc.) and a property list.
  82. (define-record-type node :node
  83. (really-make-node uid form plist)
  84. node?
  85. (uid node-operator-id)
  86. (form node-form)
  87. (plist node-plist set-node-plist!))
  88. (define-record-discloser :node
  89. (lambda (n) (list (operator-name (node-operator n)) (node-form n))))
  90. (define (make-node operator form)
  91. (really-make-node (operator-uid operator) form '()))
  92. (define (node-ref node key)
  93. (let ((probe (assq key (node-plist node))))
  94. (if probe (cdr probe) #f)))
  95. ; removes property if value is #f
  96. (define (node-set! node key value) ;gross
  97. (if value
  98. (let ((probe (assq key (node-plist node))))
  99. (if probe
  100. (set-cdr! probe value)
  101. (set-node-plist! node (cons (cons key value) (node-plist node)))))
  102. (let loop ((l (node-plist node)) (prev #f))
  103. (cond ((null? l) 'lose)
  104. ((eq? key (caar l))
  105. (if prev
  106. (set-cdr! prev (cdr l))
  107. (set-node-plist! node (cdr l))))
  108. (else (loop (cdr l) l))))))
  109. (define (node-operator node)
  110. (vector-ref the-operators (node-operator-id node)))
  111. (define (node-predicate name . type-option)
  112. (let ((id (operator-uid (apply get-operator name type-option))))
  113. (lambda (node)
  114. (= (node-operator-id node) id))))
  115. (define (make-similar-node node form)
  116. (if (equal? form (node-form node))
  117. node
  118. (make-node (node-operator node) form)))
  119. ; Top-level nodes are often delayed.
  120. (define (force-node node)
  121. (if (node? node)
  122. node
  123. (force node)))
  124. ; Node predicates and operators.
  125. (define lambda-node? (node-predicate 'lambda syntax-type))
  126. (define flat-lambda-node? (node-predicate 'flat-lambda syntax-type))
  127. (define call-node? (node-predicate 'call))
  128. (define name-node? (node-predicate 'name 'leaf))
  129. (define literal-node? (node-predicate 'literal 'leaf))
  130. (define quote-node? (node-predicate 'quote syntax-type))
  131. (define define-node? (node-predicate 'define))
  132. (define loophole-node? (node-predicate 'loophole))
  133. (define operator/flat-lambda (get-operator 'flat-lambda))
  134. (define operator/lambda (get-operator 'lambda syntax-type))
  135. (define operator/set! (get-operator 'set! syntax-type))
  136. (define operator/call (get-operator 'call 'internal))
  137. (define operator/begin (get-operator 'begin syntax-type))
  138. (define operator/name (get-operator 'name 'leaf))
  139. (define operator/letrec (get-operator 'letrec))
  140. (define operator/letrec* (get-operator 'letrec*))
  141. (define operator/pure-letrec (get-operator 'pure-letrec))
  142. (define operator/literal (get-operator 'literal))
  143. (define operator/quote (get-operator 'quote syntax-type))
  144. (define operator/unassigned (get-operator 'unassigned))
  145. (define operator/unspecific (get-operator 'unspecific (proc () unspecific-type)))
  146. (define operator/define (get-operator 'define syntax-type))
  147. (define operator/define-syntax (get-operator 'define-syntax syntax-type))
  148. (define operator/primitive-procedure
  149. (get-operator 'primitive-procedure syntax-type))
  150. (define operator/structure-ref (get-operator 'structure-ref syntax-type))