define-primitive.scm 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  3. ; These are hacked to ensure that all calls to INPUT-TYPE-PREDICATE and
  4. ; INPUT-TYPE-COERCION are evaluated at load time (because they don't
  5. ; have readily reconstructed types).
  6. (define-syntax define-primitive
  7. (syntax-rules ()
  8. ((define-primitive opcode input-types action)
  9. (define-consing-primitive opcode input-types #f action))
  10. ((define-primitive opcode input-types action returner)
  11. (define-consing-primitive opcode input-types #f action returner))))
  12. (define-syntax define-consing-primitive
  13. (syntax-rules ()
  14. ((define-consing-primitive opcode input-types space-proc action)
  15. (let ((proc (primitive-procedure-action input-types space-proc action)))
  16. (define-opcode opcode (proc))))
  17. ((define-consing-primitive opcode input-types space-proc action returner)
  18. (let ((proc (primitive-procedure-action input-types space-proc action returner)))
  19. (define-opcode opcode (proc))))))
  20. (define-syntax primitive-procedure-action
  21. (lambda (exp rename compare)
  22. (destructure (((p-p-b input-types space-proc action . returner-option) exp))
  23. (let* ((nargs (length input-types))
  24. (%action (rename 'action))
  25. (%key (rename 'key))
  26. (%ensure-space (rename 'ensure-space))
  27. (%*val* (rename '*val*))
  28. (%arg2 (rename 'arg2))
  29. (%arg3 (rename 'arg3))
  30. (%arg4 (rename 'arg4))
  31. (%arg5 (rename 'arg5))
  32. (%pop (rename 'pop))
  33. (%let (rename 'let))
  34. (%let* (rename 'let*))
  35. (%lambda (rename 'lambda))
  36. (%if (rename 'if))
  37. (%and (rename 'and))
  38. (%goto (rename 'goto))
  39. (%input-type-predicate (rename 'input-type-predicate))
  40. (%input-type-coercion (rename 'input-type-coercion))
  41. (%raise-exception (rename 'raise-exception))
  42. (%wrong-type-argument (rename 'wrong-type-argument))
  43. (shorten (lambda (l1 l2)
  44. (map (lambda (x1 x2) x2 x1) l1 l2)))
  45. (places (reverse (shorten (list %*val* %arg2 %arg3 %arg4 %arg5)
  46. input-types)))
  47. (preds (reverse (shorten (map rename
  48. '(pred1 pred2 pred3 pred4 pred5))
  49. input-types)))
  50. (x->ys (reverse (shorten (map rename
  51. '(x->y1 x->y2 x->y3 x->y4 x->y5))
  52. input-types))))
  53. (if (> nargs 5)
  54. (error "time to add more arguments to DEFINE-PRIMITIVE"))
  55. `(,%let (,@(map (lambda (type pred)
  56. `(,pred (,%input-type-predicate ,type)))
  57. input-types
  58. preds)
  59. ,@(map (lambda (type x->y)
  60. `(,x->y (,%input-type-coercion ,type)))
  61. input-types
  62. x->ys)
  63. (,%action ,action))
  64. (,%lambda ()
  65. (,%let* (,@(if space-proc
  66. `((,%key (,%ensure-space (,space-proc ,%*val*))))
  67. '())
  68. ,@(if (>= nargs 2) `((,%arg2 (,%pop))) `())
  69. ,@(if (>= nargs 3) `((,%arg3 (,%pop))) `())
  70. ,@(if (>= nargs 4) `((,%arg4 (,%pop))) `())
  71. ,@(if (>= nargs 5) `((,%arg5 (,%pop))) `())
  72. )
  73. (,%if (,%and ,@(map (lambda (pred place)
  74. `(,pred ,place))
  75. preds
  76. places))
  77. ,(let ((yow `(,%action
  78. ,@(map (lambda (x->y place)
  79. `(,x->y ,place))
  80. x->ys
  81. places)
  82. ,@(if space-proc `(,%key) '()))))
  83. (if (null? returner-option)
  84. yow
  85. `(,%goto ,(car returner-option) ,yow)))
  86. (,%raise-exception ,%wrong-type-argument
  87. 0
  88. . ,places)))))))))
  89. ;----------------
  90. ; Checking inputs and coercing results
  91. (define (input-type pred coercer) ;Alonzo wins
  92. (lambda (f) (f pred coercer)))
  93. (define (input-type-predicate type) (type (lambda (x y) y x)))
  94. (define (input-type-coercion type) (type (lambda (x y) x y)))
  95. (define (no-coercion x) x)
  96. (define any-> (input-type (lambda (x) x #t) no-coercion))
  97. (define fixnum-> (input-type fixnum? extract-fixnum))
  98. (define char-> (input-type vm-char? extract-char))
  99. (define char-scalar-value-> (input-type vm-char? char->scalar-value))
  100. (define vm-char-> (input-type vm-char? no-coercion))
  101. (define boolean-> (input-type vm-boolean? extract-boolean))
  102. (define location-> (input-type location? no-coercion))
  103. (define string-> (input-type vm-string? no-coercion))
  104. (define vector-> (input-type vm-vector? no-coercion))
  105. (define code-vector-> (input-type code-vector? no-coercion))
  106. (define vm-integer-> (input-type (lambda (x) (or (fixnum? x)
  107. (bignum? x))) no-coercion))
  108. ; Output coercion
  109. (define (return val)
  110. (set! *val* val)
  111. (goto continue 0))
  112. (define return-any return)
  113. (define (return-boolean x)
  114. (goto return (enter-boolean x)))
  115. (define (return-fixnum x)
  116. (goto return (enter-fixnum x)))
  117. (define (return-scalar-value-char x)
  118. (goto return (scalar-value->char x)))
  119. (define (return-unspecific x)
  120. x ;ignored
  121. (goto return unspecific-value))
  122. (define (no-result)
  123. (goto return unspecific-value))