/opencl/c/tsyntax.rkt

http://github.com/jeapostrophe/opencl · Racket · 187 lines · 178 code · 9 blank · 0 comment · 10 complexity · a69c7a77d101e9de7d8f49126235c6e9 MD5 · raw file

  1. #lang at-exp racket/base
  2. (require ffi/unsafe
  3. racket/bool
  4. (except-in racket/contract ->)
  5. (prefix-in c: racket/contract)
  6. (for-syntax racket/base
  7. racket/function
  8. syntax/parse
  9. racket/syntax)
  10. "util.rkt")
  11. (require scribble/srcdoc)
  12. (require/doc racket/base
  13. scribble/manual)
  14. (define-syntax-rule (define-opencl-bitfield _type _cl_bitfield valid-options _type/c
  15. (value ...))
  16. (begin (define _type (_bitmask (append `(value = ,value)
  17. ...)
  18. _cl_bitfield))
  19. (define the-symbols '(value ...))
  20. (define (symbol/c x)
  21. (and (symbol? x)
  22. (or (symbol=? 'value x)
  23. ...)))
  24. (define _type/c (or/c symbol/c (listof symbol/c)))
  25. (define valid-options the-symbols)
  26. (provide/doc
  27. (thing-doc _type ctype?
  28. @{A ctype that represents an OpenCL bitfield where @racket[valid-options] are the valid flags. It is actually a @racket[_cl_bitfield].})
  29. (thing-doc _type/c contract?
  30. @{A contract for @racket[_type] that accepts any symbol in @racket[valid-options] or lists containing subsets of @racket[valid-options].})
  31. (thing-doc valid-options (listof symbol?)
  32. @{A list of valid options for @racket[_type]. Its value is @racket['(value ...)].}))))
  33. (define-syntax-rule (define-opencl-enum _type base-type valid-options _type/c
  34. (value ...))
  35. (begin (define _type (_enum (append `(value = ,value)
  36. ...)
  37. base-type))
  38. (define the-symbols '(value ...))
  39. (define symbol/c (apply symbols the-symbols))
  40. (define _type/c symbol/c)
  41. (define valid-options the-symbols)
  42. (provide/doc
  43. (thing-doc _type ctype?
  44. @{A ctype that represents an OpenCL enumeration, implemented by @racket[base-type], where @racket[valid-options] are the valid values.})
  45. (thing-doc _type/c contract?
  46. @{A contract for @racket[_type] that accepts any symbol in @racket[valid-options].})
  47. (thing-doc valid-options (listof symbol?)
  48. @{A list of valid options for @racket[_type]. Its value is @racket['(value ...)].}))))
  49. (define-for-syntax (stxformat fmt stx . others)
  50. (datum->syntax stx
  51. (string->symbol
  52. (apply format fmt (syntax->datum stx)
  53. (map syntax->datum others)))
  54. stx))
  55. (define-syntax (define-opencl-pointer stx)
  56. (syntax-case stx ()
  57. [(_ _id)
  58. (with-syntax ([_id/c (stxformat "~a/c" #'_id)]
  59. [_id/null (stxformat "~a/null" #'_id)]
  60. [id? (datum->syntax
  61. stx
  62. (string->symbol
  63. (format "~a?"
  64. (substring
  65. (symbol->string
  66. (syntax->datum #'_id))
  67. 1))))]
  68. [_id/null/c (stxformat "~a/null/c" #'_id)]
  69. [_id_vector/c (stxformat "~a_vector/c" #'_id)])
  70. (syntax/loc stx
  71. (begin (define-cpointer-type _id)
  72. (define _id/c id?)
  73. (define _id/null/c (or/c false/c id?))
  74. (define _id_vector/c (cvector-of? _id))
  75. (provide/doc
  76. (thing-doc _id ctype?
  77. @{Represents a pointer to a particular kind of OpenCL object.})
  78. (thing-doc _id/null ctype?
  79. @{Represents a pointer to a particular kind of OpenCL object that may be NULL.})
  80. (thing-doc _id/c contract?
  81. @{A contract for @racket[_id] values.})
  82. (thing-doc _id/null/c contract?
  83. @{A contract for @racket[_id] values that includes NULL pointers, represented by @racket[#f].})
  84. (thing-doc _id_vector/c contract?
  85. @{A contract for @racket[cvector]s of @racket[_id] values.})))))]))
  86. (define-syntax (define-opencl-cstruct stx)
  87. (syntax-case stx ()
  88. [(_ _id ([field _type] ...))
  89. (with-syntax ([id (datum->syntax
  90. #'_id
  91. (string->symbol
  92. (substring
  93. (symbol->string
  94. (syntax->datum #'_id))
  95. 1))
  96. #'_id)])
  97. (with-syntax ([_id/c (stxformat "~a/c" #'_id)]
  98. [_id-pointer (stxformat "~a-pointer" #'_id)]
  99. [id? (stxformat "~a?" #'id)]
  100. [_id_vector/c (stxformat "~a_vector/c" #'_id)]
  101. [make-id (stxformat "make-~a" #'id)]
  102. [(_type/c ...)
  103. (map (curry stxformat "~a/c")
  104. (syntax->list #'(_type ...)))]
  105. [(_id-field ...)
  106. (map (curry stxformat "~a-~a" #'id)
  107. (syntax->list #'(field ...)))]
  108. [(set-_id-field! ...)
  109. (map (curry stxformat "set-~a-~a!" #'id)
  110. (syntax->list #'(field ...)))])
  111. (syntax/loc stx
  112. (begin (define-cstruct _id
  113. ([field _type] ...))
  114. (define _id/c id?)
  115. (define _id_vector/c (cvector-of? _id))
  116. (provide/doc
  117. (thing-doc _id ctype?
  118. @{Represents a structure value of a particular kind of OpenCL object.})
  119. (thing-doc _id-pointer ctype?
  120. @{Represents a pointer to a particular kind of OpenCL object.})
  121. (proc-doc/names make-id
  122. (c:-> _type/c ... _id/c)
  123. (field ...)
  124. @{Constructs a @racket[_id] value.})
  125. (proc-doc/names _id-field
  126. (c:-> _id/c _type/c)
  127. (obj)
  128. @{Extracts the @racket[field] of a @racket[_id] value.})
  129. ...
  130. (proc-doc/names set-_id-field!
  131. (c:-> _id/c _type/c void)
  132. (obj v)
  133. @{Sets the @racket[field] of a @racket[_id] value.})
  134. ...
  135. (thing-doc _id/c contract?
  136. @{A contract for @racket[_id] values.})
  137. (thing-doc _id_vector/c contract?
  138. @{A contract for cvectors of @racket[_id] values.}))))))]))
  139. (define-syntax (define-opencl-alias stx)
  140. (syntax-case stx ()
  141. [(_ _opencl_type _ctype contract-expr)
  142. (with-syntax ([_opencl_type/c (stxformat "~a/c" #'_opencl_type)]
  143. [_opencl_type_vector/c (stxformat "~a_vector/c" #'_opencl_type)])
  144. (syntax/loc stx
  145. (begin (define _opencl_type _ctype)
  146. (define _opencl_type/c contract-expr)
  147. (define _opencl_type_vector/c (cvector-of? _opencl_type))
  148. (provide/doc
  149. (thing-doc _opencl_type ctype?
  150. @{An alias for @racket[_ctype].})
  151. (thing-doc _opencl_type/c contract?
  152. @{A contract for @racket[_opencl_type] values. Defined as @racket[contract-expr].})
  153. (thing-doc _opencl_type_vector/c contract?
  154. @{A contract for vectors of @racket[_opencl_type] values.})))))]))
  155. (define-syntax (define-opencl-vector-alias stx)
  156. (syntax-parse
  157. stx
  158. [(_ _type:id N:number)
  159. (let ([Nnum (syntax->datum #'N)])
  160. (with-syntax
  161. ([(fi ...)
  162. (for/list ([i (in-range Nnum)])
  163. (format-id stx "f~a" i))]
  164. [_typeN
  165. (format-id #'_type "~a~a" #'_type Nnum #:source #'_type)])
  166. (syntax/loc stx
  167. (define-opencl-cstruct _typeN ([fi _type] ...)))))]))
  168. (define-syntax-rule (define-opencl-vector-alias* id n ...)
  169. (begin (define-opencl-vector-alias id n)
  170. ...))
  171. (provide define-opencl-bitfield
  172. define-opencl-enum
  173. define-opencl-pointer
  174. define-opencl-cstruct
  175. define-opencl-alias
  176. define-opencl-vector-alias
  177. define-opencl-vector-alias*
  178. (for-syntax stxformat))