primitives.scm 12 KB

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