primitives.scm 14 KB

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