ascii.scm 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees. See file COPYING.
  3. ;;;; Portable definitions of char->ascii and ascii->char
  4. ; Don't detabify this file!
  5. ; This module defines char->ascii and ascii->char in terms of
  6. ; char->integer and integer->char, with no assumptions about the encoding.
  7. ; Portable except maybe for the strings that contain tab, page, and
  8. ; carriage return characters. Those can be flushed if necessary.
  9. (define ascii-limit 128)
  10. (define ascii-chars
  11. (let* ((ascii-chars (make-vector ascii-limit #f))
  12. (unusual (lambda (s)
  13. (if (or (not (= (string-length s) 1))
  14. (let ((c (string-ref s 0)))
  15. (or (char=? c #\space)
  16. (char=? c #\newline))))
  17. (error "unusual whitespace character lost" s)
  18. s)))
  19. (init (lambda (i s)
  20. (do ((i i (+ i 1))
  21. (j 0 (+ j 1)))
  22. ((= j (string-length s)))
  23. (vector-set! ascii-chars i (string-ref s j))))))
  24. (init 9 (unusual " ")) ;tab
  25. (init 12 (unusual " ")) ;page
  26. (init 13 (unusual " ")) ;carriage return
  27. (init 10 (string #\newline))
  28. (init 32 " !\"#$%&'()*+,-./0123456789:;<=>?")
  29. (init 64 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_")
  30. (init 96 "`abcdefghijklmnopqrstuvwxyz{|}~")
  31. ascii-chars))
  32. (define (ascii->char n)
  33. (or (vector-ref ascii-chars n)
  34. (error "not a standard character's ASCII code" n)))
  35. (define native-chars
  36. (let ((end (vector-length ascii-chars)))
  37. (let loop ((i 0)
  38. (least #f)
  39. (greatest #f))
  40. (cond ((= i end)
  41. (let ((v (make-vector (+ (- greatest least) 1) #f)))
  42. (do ((i 0 (+ i 1)))
  43. ((= i end) (cons least v))
  44. (let ((c (vector-ref ascii-chars i)))
  45. (if c
  46. (vector-set! v (- (char->integer c) least) i))))))
  47. (else
  48. (let ((c (vector-ref ascii-chars i)))
  49. (if c
  50. (let ((n (char->integer c)))
  51. (loop (+ i 1)
  52. (if least (min least n) n)
  53. (if greatest (max greatest n) n)))
  54. (loop (+ i 1) least greatest))))))))
  55. (define (char->ascii char)
  56. (or (vector-ref (cdr native-chars)
  57. (- (char->integer char) (car native-chars)))
  58. (error "not a standard character" char)))
  59. (define ascii-whitespaces '(32 10 9 12 13)) ;space linefeed tab page return