generate-old-c-header.scm 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ; This for compatibility with pre-0.53 code.
  4. ; [This is a kludge. Richard is loathe to include it in the
  5. ; distribution.]
  6. ; Reads arch.scm and data.scm and writes out a C .h file with constants
  7. ; and macros for dealing with Scheme 48 data structures.
  8. ; Needs Big Scheme.
  9. ; (make-c-header-file "scheme48.h" "vm/arch.scm" "vm/data.scm")
  10. (define (make-c-header-file c-file arch-file data-file)
  11. (receive (stob-list stob-data)
  12. (search-file arch-file
  13. '("stob enumeration" "(define stob-data ...)")
  14. (defines-enum? 'stob)
  15. enum-definition-list
  16. (lambda (x)
  17. (and (eq? (car x) 'define)
  18. (eq? (cadr x) 'stob-data)))
  19. (lambda (x) (cadr (caddr x))))
  20. (receive (tag-list immediate-list)
  21. (search-file data-file
  22. '("tag enumeration" "imm enumeration")
  23. (defines-enum? 'tag)
  24. enum-definition-list
  25. (defines-enum? 'imm)
  26. enum-definition-list)
  27. (with-output-to-file c-file
  28. (lambda ()
  29. (format #t "typedef long scheme_value;~%~%")
  30. (tag-stuff tag-list)
  31. (newline)
  32. (immediate-stuff immediate-list)
  33. (newline)
  34. (stob-stuff stob-list stob-data))))))
  35. (define (tag-stuff tag-list)
  36. (do ((tags tag-list (cdr tags))
  37. (i 0 (+ i 1)))
  38. ((null? tags))
  39. (let ((name (upcase (car tags))))
  40. (c-define "~A_TAG ~D" name i)
  41. (c-define "~AP(x) (((long)(x) & 3L) == ~A_TAG)" name name)))
  42. (newline)
  43. (c-define "ENTER_FIXNUM(n) ((scheme_value)((n) << 2))")
  44. (c-define "EXTRACT_FIXNUM(x) ((long)(x) >> 2)"))
  45. (define (immediate-stuff imm-list)
  46. (c-define "MISC_IMMEDIATE(n) (scheme_value)(IMMEDIATE_TAG | ((n) << 2))")
  47. (do ((imm imm-list (cdr imm))
  48. (i 0 (+ i 1)))
  49. ((null? imm))
  50. (let ((name (upcase (car imm))))
  51. (c-define "SCH~A MISC_IMMEDIATE(~D)" name i)))
  52. (c-define "UNDEFINED SCHUNDEFINED")
  53. (c-define "UNSPECIFIC SCHUNSPECIFIC")
  54. (newline)
  55. (c-define "ENTER_BOOLEAN(n) ((n) ? SCHTRUE : SCHFALSE)")
  56. (c-define "EXTRACT_BOOLEAN(x) ((x) != SCHFALSE)")
  57. (newline)
  58. (c-define "ENTER_CHAR(c) (SCHCHAR | ((c) << 8))")
  59. (c-define "EXTRACT_CHAR(x) ((x) >> 8)")
  60. (c-define "CHARP(x) ((((long) (x)) & 0xff) == SCHCHAR)"))
  61. (define (stob-stuff stob-list stob-data)
  62. (let ((type-mask (let ((len (length stob-list)))
  63. (do ((i 2 (* i 2)))
  64. ((>= i len) (- i 1))))))
  65. (c-define "ADDRESS_AFTER_HEADER(x, type) ((type *)((x) - STOB_TAG))")
  66. (c-define "STOB_REF(x, i) ((ADDRESS_AFTER_HEADER(x, long))[i])")
  67. (c-define "STOB_TYPE(x) ((STOB_HEADER(x)>>2)&~D)" type-mask)
  68. (c-define "STOB_HEADER(x) (STOB_REF((x),-1))")
  69. (c-define "STOB_BLENGTH(x) (STOB_HEADER(x) >> 8)")
  70. (c-define "STOB_LLENGTH(x) (STOB_HEADER(x) >> 10)")
  71. (newline)
  72. (do ((stob stob-list (cdr stob))
  73. (i 0 (+ i 1)))
  74. ((null? stob))
  75. (let ((name (upcase (if (eq? (car stob) 'byte-vector)
  76. 'code-vector
  77. (car stob)))))
  78. (c-define "STOBTYPE_~A ~D" name i)
  79. (c-define "~AP(x) (STOBP(x) && (STOB_TYPE(x) == STOBTYPE_~A))"
  80. name name)))
  81. (newline)
  82. (for-each (lambda (data)
  83. (do ((accs (cdddr data) (cdr accs))
  84. (i 0 (+ i 1)))
  85. ((null? accs))
  86. (let ((name (upcase (caar accs))))
  87. (c-define "~A(x) STOB_REF(x, ~D)" name i))))
  88. stob-data)
  89. (newline)
  90. (c-define "VECTOR_LENGTH(x) STOB_LLENGTH(x)")
  91. (c-define "VECTOR_REF(x, i) STOB_REF(x, i)")
  92. (c-define "CODE_VECTOR_LENGTH(x) STOB_BLENGTH(x)")
  93. (c-define "CODE_VECTOR_REF(x, i) (ADDRESS_AFTER_HEADER(x, unsigned char)[i])")
  94. (c-define "STRING_LENGTH(x) (STOB_BLENGTH(x)-1)")
  95. (c-define "STRING_REF(x, i) (ADDRESS_AFTER_HEADER(x, char)[i])")))
  96. ; - becomes _ > becomes TO_ (so -> turns into _TO_)
  97. ; ? becomes P
  98. (define (upcase symbol)
  99. (do ((chars (string->list (symbol->string symbol)) (cdr chars))
  100. (res '() (case (car chars)
  101. ((#\>) (append (string->list "_OT") res))
  102. ((#\-) (cons #\_ res))
  103. ((#\?) (cons #\P res))
  104. (else (cons (char-upcase (car chars)) res)))))
  105. ((null? chars)
  106. (list->string (reverse res)))))
  107. (define (c-define string . stuff)
  108. (format #t "#define ~?~%" string stuff))
  109. (define (defines-enum? name)
  110. (lambda (x)
  111. (and (eq? (car x) 'define-enumeration)
  112. (eq? (cadr x) name))))
  113. (define enum-definition-list caddr)
  114. ; STUFF is list of ((predicate . extract) . name). <name> is replaced
  115. ; with the value when it is found.
  116. (define (search-file file what-for . pred+extract)
  117. (let ((stuff (do ((p+e pred+extract (cddr p+e))
  118. (names what-for (cdr names))
  119. (ps '() (cons (cons (cons (car p+e) (cadr p+e))
  120. (car names))
  121. ps)))
  122. ((null? p+e) (reverse ps)))))
  123. (define (search next not-found)
  124. (let loop ((n-f not-found) (checked '()))
  125. (cond ((null? n-f)
  126. #f)
  127. (((caaar n-f) next)
  128. (set-cdr! (car n-f) ((cdaar n-f) next))
  129. (append (reverse checked) (cdr n-f)))
  130. (else
  131. (loop (cdr n-f) (cons (car n-f) checked))))))
  132. (with-input-from-file file
  133. (lambda ()
  134. (let loop ((not-found stuff))
  135. (let ((next (read)))
  136. (cond ((null? not-found)
  137. (apply values (map cdr stuff)))
  138. ((eof-object? next)
  139. (error "file ~S doesn't have ~A" file (cdar not-found)))
  140. (else
  141. (loop (or (and (pair? next)
  142. (search next not-found))
  143. not-found))))))))))