glil.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ;;; Guile Low Intermediate Language
  2. ;; Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free Software
  15. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;; Code:
  17. (define-module (language glil)
  18. #:use-module (system base syntax)
  19. #:use-module (system base pmatch)
  20. #:use-module ((srfi srfi-1) #:select (fold))
  21. #:export
  22. (<glil-program> make-glil-program glil-program?
  23. glil-program-meta glil-program-body
  24. <glil-std-prelude> make-glil-std-prelude glil-std-prelude?
  25. glil-std-prelude-nreq glil-std-prelude-nlocs glil-std-prelude-else-label
  26. <glil-opt-prelude> make-glil-opt-prelude glil-opt-prelude?
  27. glil-opt-prelude-nreq glil-opt-prelude-nopt glil-opt-prelude-rest
  28. glil-opt-prelude-nlocs glil-opt-prelude-else-label
  29. <glil-kw-prelude> make-glil-kw-prelude glil-kw-prelude?
  30. glil-kw-prelude-nreq glil-kw-prelude-nopt glil-kw-prelude-kw
  31. glil-kw-prelude-allow-other-keys? glil-kw-prelude-rest
  32. glil-kw-prelude-nlocs glil-kw-prelude-else-label
  33. <glil-bind> make-glil-bind glil-bind?
  34. glil-bind-vars
  35. <glil-mv-bind> make-glil-mv-bind glil-mv-bind?
  36. glil-mv-bind-vars glil-mv-bind-rest
  37. <glil-unbind> make-glil-unbind glil-unbind?
  38. <glil-source> make-glil-source glil-source?
  39. glil-source-props
  40. <glil-void> make-glil-void glil-void?
  41. <glil-const> make-glil-const glil-const?
  42. glil-const-obj
  43. <glil-lexical> make-glil-lexical glil-lexical?
  44. glil-lexical-local? glil-lexical-boxed? glil-lexical-op glil-lexical-index
  45. <glil-toplevel> make-glil-toplevel glil-toplevel?
  46. glil-toplevel-op glil-toplevel-name
  47. <glil-module> make-glil-module glil-module?
  48. glil-module-op glil-module-mod glil-module-name glil-module-public?
  49. <glil-label> make-glil-label glil-label?
  50. glil-label-label
  51. <glil-branch> make-glil-branch glil-branch?
  52. glil-branch-inst glil-branch-label
  53. <glil-call> make-glil-call glil-call?
  54. glil-call-inst glil-call-nargs
  55. <glil-mv-call> make-glil-mv-call glil-mv-call?
  56. glil-mv-call-nargs glil-mv-call-ra
  57. <glil-prompt> make-glil-prompt glil-prompt? glil-prompt-label glil-prompt-escape-only?
  58. parse-glil unparse-glil))
  59. (define (print-glil x port)
  60. (format port "#<glil ~s>" (unparse-glil x)))
  61. (define-type (<glil> #:printer print-glil)
  62. ;; Meta operations
  63. (<glil-program> meta body)
  64. (<glil-std-prelude> nreq nlocs else-label)
  65. (<glil-opt-prelude> nreq nopt rest nlocs else-label)
  66. (<glil-kw-prelude> nreq nopt rest kw allow-other-keys? nlocs else-label)
  67. (<glil-bind> vars)
  68. (<glil-mv-bind> vars rest)
  69. (<glil-unbind>)
  70. (<glil-source> props)
  71. ;; Objects
  72. (<glil-void>)
  73. (<glil-const> obj)
  74. ;; Variables
  75. (<glil-lexical> local? boxed? op index)
  76. (<glil-toplevel> op name)
  77. (<glil-module> op mod name public?)
  78. ;; Controls
  79. (<glil-label> label)
  80. (<glil-branch> inst label)
  81. (<glil-call> inst nargs)
  82. (<glil-mv-call> nargs ra)
  83. (<glil-prompt> label escape-only?))
  84. (define (parse-glil x)
  85. (pmatch x
  86. ((program ,meta . ,body)
  87. (make-glil-program meta (map parse-glil body)))
  88. ((std-prelude ,nreq ,nlocs ,else-label)
  89. (make-glil-std-prelude nreq nlocs else-label))
  90. ((opt-prelude ,nreq ,nopt ,rest ,nlocs ,else-label)
  91. (make-glil-opt-prelude nreq nopt rest nlocs else-label))
  92. ((kw-prelude ,nreq ,nopt ,rest ,kw ,allow-other-keys? ,nlocs ,else-label)
  93. (make-glil-kw-prelude nreq nopt rest kw allow-other-keys? nlocs else-label))
  94. ((bind . ,vars) (make-glil-bind vars))
  95. ((mv-bind ,vars ,rest) (make-glil-mv-bind vars rest))
  96. ((unbind) (make-glil-unbind))
  97. ((source ,props) (make-glil-source props))
  98. ((void) (make-glil-void))
  99. ((const ,obj) (make-glil-const obj))
  100. ((lexical ,local? ,boxed? ,op ,index) (make-glil-lexical local? boxed? op index))
  101. ((toplevel ,op ,name) (make-glil-toplevel op name))
  102. ((module public ,op ,mod ,name) (make-glil-module op mod name #t))
  103. ((module private ,op ,mod ,name) (make-glil-module op mod name #f))
  104. ((label ,label) (make-glil-label label))
  105. ((branch ,inst ,label) (make-glil-branch inst label))
  106. ((call ,inst ,nargs) (make-glil-call inst nargs))
  107. ((mv-call ,nargs ,ra) (make-glil-mv-call nargs ra))
  108. ((prompt ,label ,escape-only?)
  109. (make-glil-prompt label escape-only?))
  110. (else (error "invalid glil" x))))
  111. (define (unparse-glil glil)
  112. (record-case glil
  113. ;; meta
  114. ((<glil-program> meta body)
  115. `(program ,meta ,@(map unparse-glil body)))
  116. ((<glil-std-prelude> nreq nlocs else-label)
  117. `(std-prelude ,nreq ,nlocs ,else-label))
  118. ((<glil-opt-prelude> nreq nopt rest nlocs else-label)
  119. `(opt-prelude ,nreq ,nopt ,rest ,nlocs ,else-label))
  120. ((<glil-kw-prelude> nreq nopt rest kw allow-other-keys? nlocs else-label)
  121. `(kw-prelude ,nreq ,nopt ,rest ,kw ,allow-other-keys? ,nlocs ,else-label))
  122. ((<glil-bind> vars) `(bind ,@vars))
  123. ((<glil-mv-bind> vars rest) `(mv-bind ,vars ,rest))
  124. ((<glil-unbind>) `(unbind))
  125. ((<glil-source> props) `(source ,props))
  126. ;; constants
  127. ((<glil-void>) `(void))
  128. ((<glil-const> obj) `(const ,obj))
  129. ;; variables
  130. ((<glil-lexical> local? boxed? op index)
  131. `(lexical ,local? ,boxed? ,op ,index))
  132. ((<glil-toplevel> op name)
  133. `(toplevel ,op ,name))
  134. ((<glil-module> op mod name public?)
  135. `(module ,(if public? 'public 'private) ,op ,mod ,name))
  136. ;; controls
  137. ((<glil-label> label) `(label ,label))
  138. ((<glil-branch> inst label) `(branch ,inst ,label))
  139. ((<glil-call> inst nargs) `(call ,inst ,nargs))
  140. ((<glil-mv-call> nargs ra) `(mv-call ,nargs ,ra))
  141. ((<glil-prompt> label escape-only?)
  142. `(prompt ,label escape-only?))))