primitives.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. ;;; Hoot primitives
  2. ;;; Copyright (C) 2023 Igalia, S.L.
  3. ;;;
  4. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  5. ;;; you may not use this file except in compliance with the License.
  6. ;;; You may obtain a copy of the License at
  7. ;;;
  8. ;;; http://www.apache.org/licenses/LICENSE-2.0
  9. ;;;
  10. ;;; Unless required by applicable law or agreed to in writing, software
  11. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  12. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. ;;; See the License for the specific language governing permissions and
  14. ;;; limitations under the License.
  15. ;;; Commentary:
  16. ;;;
  17. ;;; This file exists only to be a place to define primitives for use by
  18. ;;; Hoot user code. It also exports implementation-detail primitives
  19. ;;; for use by the Hoot standard library; eventually this will change to
  20. ;;; avoid exposing these nonstandard primitives to users.
  21. ;;;
  22. ;;; Code:
  23. (define-module (hoot primitives)
  24. #:pure
  25. #:use-module ((guile)
  26. #:select
  27. (include-from-path
  28. define-syntax-rule
  29. syntax-case syntax quasisyntax unsyntax unsyntax-splicing
  30. syntax->datum datum->syntax identifier?
  31. generate-temporaries free-identifier=? bound-identifier=?
  32. with-syntax identifier-syntax
  33. syntax-violation procedure-property
  34. lambda* case-lambda* define*
  35. call-with-prompt abort-to-prompt
  36. ash logand logior logxor lognot logtest logbit?
  37. keyword?
  38. bitvector?
  39. cons*
  40. fluid-ref fluid-set! with-fluid* with-dynamic-state
  41. make-variable variable-ref variable-set!
  42. keyword->symbol symbol->keyword
  43. exact->inexact
  44. error
  45. raise-exception
  46. eval-when
  47. make-struct/simple struct? struct-vtable
  48. struct-ref struct-set!
  49. gensym
  50. string-utf8-length))
  51. #:use-module ((system syntax internal) #:select (syntax-local-binding))
  52. ;; A bug in Guile: the public interface of (guile) uses (ice-9 ports),
  53. ;; which should re-export all its bindings, but #:select doesn't work
  54. ;; on interfaces that use interfaces. For now, import the-eof-object
  55. ;; from (ice-9 ports) instead.
  56. #:use-module ((ice-9 ports) #:select (the-eof-object))
  57. #:use-module ((ice-9 atomic)
  58. #:select
  59. (make-atomic-box
  60. atomic-box-ref atomic-box-set!
  61. atomic-box-swap! atomic-box-compare-and-swap!))
  62. #:use-module ((rnrs bytevectors)
  63. #:select
  64. (bytevector?
  65. bytevector-length
  66. bytevector-u8-ref bytevector-u8-set!
  67. bytevector-s8-ref bytevector-s8-set!
  68. bytevector-u16-native-ref bytevector-u16-native-set!
  69. bytevector-s16-native-ref bytevector-s16-native-set!
  70. bytevector-u32-native-ref bytevector-u32-native-set!
  71. bytevector-s32-native-ref bytevector-s32-native-set!
  72. bytevector-u64-native-ref bytevector-u64-native-set!
  73. bytevector-s64-native-ref bytevector-s64-native-set!
  74. bytevector-ieee-single-native-ref
  75. bytevector-ieee-single-native-set!
  76. bytevector-ieee-double-native-ref
  77. bytevector-ieee-double-native-set!
  78. string->utf8 utf8->string))
  79. #:use-module ((scheme base)
  80. #:select
  81. (_
  82. ... => else
  83. lambda
  84. define define-values let let* letrec letrec*
  85. let-values let*-values
  86. or and
  87. begin
  88. if cond case when unless
  89. do
  90. set!
  91. quote quasiquote unquote unquote-splicing
  92. include include-ci
  93. define-syntax let-syntax letrec-syntax
  94. syntax-rules syntax-error
  95. parameterize
  96. guard
  97. ;; R7RS control
  98. dynamic-wind
  99. ;; R7RS values
  100. values
  101. call-with-values
  102. apply
  103. ;; R7RS pairs
  104. pair?
  105. cons
  106. car
  107. cdr
  108. set-car!
  109. set-cdr!
  110. ;; R7RS lists
  111. null?
  112. append
  113. ;; R7RS numerics
  114. *
  115. +
  116. -
  117. /
  118. <
  119. <=
  120. =
  121. >
  122. >=
  123. abs
  124. floor
  125. ceiling
  126. number?
  127. complex?
  128. real?
  129. rational?
  130. integer?
  131. exact-integer?
  132. exact?
  133. inexact?
  134. quotient
  135. remainder
  136. modulo
  137. ;; R7RS chars
  138. char->integer
  139. integer->char
  140. char?
  141. ;; R7RS ports
  142. eof-object?
  143. ;; Parameters
  144. ;; R7RS equality
  145. eq?
  146. eqv?
  147. ;; R7RS strings
  148. string?
  149. string-length
  150. string-ref
  151. ;; Symbols
  152. symbol?
  153. symbol->string
  154. string->symbol
  155. ;; R7RS vectors
  156. vector?
  157. make-vector
  158. vector
  159. vector-length
  160. vector-ref
  161. vector-set!
  162. procedure?))
  163. #:use-module ((scheme case-lambda)
  164. #:select (case-lambda))
  165. #:use-module ((scheme inexact)
  166. #:select (inexact sin cos tan asin acos atan sqrt))
  167. #:re-export
  168. ( ;; R7RS syntax
  169. _
  170. ... => else
  171. lambda case-lambda
  172. define define-values let let* letrec letrec* let-values let*-values
  173. or and
  174. begin
  175. if cond case when unless
  176. do
  177. set!
  178. quote quasiquote unquote unquote-splicing
  179. include include-ci
  180. define-syntax let-syntax letrec-syntax
  181. syntax-rules syntax-error
  182. ;; FIXME: These two need Hoot support.
  183. ;; guard
  184. ;; Most primitives can only appear in primcalls, so we expose them as
  185. ;; %foo instead of foo, relying on the prelude to wrap them in
  186. ;; lambdas to ensure they are always called with the right number of
  187. ;; arguments, even when used as a value. The three exceptions are
  188. ;; `apply`, `abort-to-prompt`, and `values`.
  189. ;; Guile syntax extensions
  190. include-from-path
  191. define-syntax-rule
  192. syntax-case syntax quasisyntax unsyntax unsyntax-splicing
  193. syntax->datum datum->syntax
  194. identifier? generate-temporaries free-identifier=? bound-identifier=?
  195. with-syntax identifier-syntax syntax-local-binding
  196. syntax-violation procedure-property
  197. gensym
  198. lambda* case-lambda* define*
  199. ;; R7RS control
  200. (dynamic-wind . %dynamic-wind)
  201. ;; R7RS values
  202. values
  203. (call-with-values . %call-with-values)
  204. apply
  205. ;; R7RS pairs
  206. (pair? . %pair?)
  207. (cons . %cons)
  208. (car . %car)
  209. (cdr . %cdr)
  210. (set-car! . %set-car!)
  211. (set-cdr! . %set-cdr!)
  212. ;; R7RS lists
  213. (null? . %null?)
  214. (append . %append)
  215. ;; R7RS bytevectors
  216. (bytevector-length . %bytevector-length)
  217. (bytevector-u8-ref . %bytevector-u8-ref)
  218. (bytevector-u8-set! . %bytevector-u8-set!)
  219. (bytevector? . %bytevector?)
  220. (string->utf8 . %string->utf8)
  221. (utf8->string . %utf8->string)
  222. (string-utf8-length . %string-utf8-length)
  223. ;; R7RS numerics
  224. (* . %*)
  225. (+ . %+)
  226. (- . %-)
  227. (/ . %/)
  228. (< . %<)
  229. (<= . %<=)
  230. (= . %=)
  231. (> . %>)
  232. (>= . %>=)
  233. (abs . %abs)
  234. (floor . %floor)
  235. (ceiling . %ceiling)
  236. (number? . %number?)
  237. (complex? . %complex?)
  238. (real? . %real?)
  239. (rational? . %rational?)
  240. (integer? . %integer?)
  241. (exact-integer? . %exact-integer?)
  242. (exact? . %exact?)
  243. (inexact? . %inexact?)
  244. ;; FIXME: we should actually be using the R7RS variants which are
  245. ;; slightly different than Guile's.
  246. (inexact . %inexact)
  247. (quotient . %quotient)
  248. (remainder . %remainder)
  249. (modulo . %modulo)
  250. (sin . %sin)
  251. (cos . %cos)
  252. (tan . %tan)
  253. (asin . %asin)
  254. (acos . %acos)
  255. (atan . %atan)
  256. (sqrt . %sqrt)
  257. ;; R7RS chars
  258. (char->integer . %char->integer)
  259. (integer->char . %integer->char)
  260. (char? . %char?)
  261. ;; R7RS ports
  262. (eof-object? . %eof-object?)
  263. ;; Parameters
  264. ;; R7RS equality
  265. (eq? . %eq?)
  266. (eqv? . %eqv?)
  267. ;; R7RS strings
  268. (string? . %string?)
  269. (string-length . %string-length)
  270. (string-ref . %string-ref)
  271. ;; Symbols
  272. (symbol? . %symbol?)
  273. (symbol->string . %symbol->string)
  274. (string->symbol . %string->symbol)
  275. ;; Keywords
  276. (symbol->keyword . %symbol->keyword)
  277. (keyword->symbol . %keyword->symbol)
  278. ;; R7RS vectors
  279. (vector? . %vector?)
  280. (make-vector . %make-vector)
  281. (vector . %vector)
  282. (vector-length . %vector-length)
  283. (vector-ref . %vector-ref)
  284. (vector-set! . %vector-set!)
  285. ;; Error handling
  286. (error . %error)
  287. (raise-exception . %raise-exception)
  288. (procedure? . %procedure?)
  289. ;; guile extensions
  290. (call-with-prompt . %call-with-prompt)
  291. abort-to-prompt
  292. (ash . %ash)
  293. (logand . %logand)
  294. (logior . %logior)
  295. (logxor . %logxor)
  296. (lognot . %lognot)
  297. (logtest . %logtest)
  298. (logbit? . %logbit?)
  299. (keyword? . %keyword?)
  300. (bitvector? . %bitvector?)
  301. (cons* . %cons*)
  302. (fluid-ref . %fluid-ref)
  303. (fluid-set! . %fluid-set!)
  304. (with-fluid* . %with-fluid*)
  305. (with-dynamic-state . %with-dynamic-state)
  306. (make-atomic-box . %make-atomic-box)
  307. (atomic-box-ref . %atomic-box-ref)
  308. (atomic-box-set! . %atomic-box-set!)
  309. (atomic-box-swap! . %atomic-box-swap!)
  310. (atomic-box-compare-and-swap! . %atomic-box-compare-and-swap!)
  311. (bytevector-s8-ref . %bytevector-s8-ref)
  312. (bytevector-s8-set! . %bytevector-s8-set!)
  313. (bytevector-u16-native-ref . %bytevector-u16-native-ref)
  314. (bytevector-u16-native-set! . %bytevector-u16-native-set!)
  315. (bytevector-s16-native-ref . %bytevector-s16-native-ref)
  316. (bytevector-s16-native-set! . %bytevector-s16-native-set!)
  317. (bytevector-u32-native-ref . %bytevector-u32-native-ref)
  318. (bytevector-u32-native-set! . %bytevector-u32-native-set!)
  319. (bytevector-s32-native-ref . %bytevector-s32-native-ref)
  320. (bytevector-s32-native-set! . %bytevector-s32-native-set!)
  321. (bytevector-u64-native-ref . %bytevector-u64-native-ref)
  322. (bytevector-u64-native-set! . %bytevector-u64-native-set!)
  323. (bytevector-s64-native-ref . %bytevector-s64-native-ref)
  324. (bytevector-s64-native-set! . %bytevector-s64-native-set!)
  325. (bytevector-ieee-single-native-ref . %bytevector-ieee-single-native-ref)
  326. (bytevector-ieee-single-native-set! . %bytevector-ieee-single-native-set!)
  327. (bytevector-ieee-double-native-ref . %bytevector-ieee-double-native-ref)
  328. (bytevector-ieee-double-native-set! . %bytevector-ieee-double-native-set!)
  329. (the-eof-object . %the-eof-object)
  330. (make-variable . %make-box)
  331. (variable-ref . %box-ref)
  332. (variable-set! . %box-set!)
  333. (make-struct/simple . %make-struct)
  334. (struct? . %struct?)
  335. (struct-vtable . %struct-vtable)
  336. (struct-ref . %struct-ref)
  337. (struct-set! . %struct-set!))
  338. #:export (%inline-wasm %wasm-import)
  339. ;; Mark as non-declarative, as we should not have inlinable exports.
  340. #:declarative? #f)
  341. (define (%inline-wasm code . args)
  342. "Emit inline WebAssembly code. @var{code} is a WebAssembly module
  343. expressed in WebAssembly's s-expression syntax. The backend expects the
  344. parsed module to contain a single function. The arguments
  345. @var{arg}... should correspond to the parameters of the function. The
  346. number of result values is also determined from the function signature."
  347. (error "target-only primitive"))
  348. (define (%wasm-import code)
  349. "Emit WebAssembly import. @var{code} is a WebAssembly module
  350. expressed in WebAssembly's s-expression syntax. The backend expects the
  351. parsed module to contain a single import."
  352. (error "target-only primitive"))
  353. ;(add-interesting-primitive! '%inline-asm)