format.scm 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. (define-module (lang elisp internals format)
  2. #:pure
  3. #:use-module (ice-9 r5rs)
  4. #:use-module ((ice-9 format) #:select ((format . scheme:format)))
  5. #:use-module (lang elisp internals fset)
  6. #:use-module (lang elisp internals signal)
  7. #:replace (format)
  8. #:export (message))
  9. (define (format control-string . args)
  10. (define (cons-string str ls)
  11. (let loop ((sl (string->list str))
  12. (ls ls))
  13. (if (null? sl)
  14. ls
  15. (loop (cdr sl) (cons (car sl) ls)))))
  16. (let loop ((input (string->list control-string))
  17. (args args)
  18. (output '())
  19. (mid-control #f))
  20. (if (null? input)
  21. (if mid-control
  22. (error "Format string ends in middle of format specifier")
  23. (list->string (reverse output)))
  24. (if mid-control
  25. (case (car input)
  26. ((#\%)
  27. (loop (cdr input)
  28. args
  29. (cons #\% output)
  30. #f))
  31. (else
  32. (loop (cdr input)
  33. (cdr args)
  34. (cons-string (case (car input)
  35. ((#\s) (scheme:format #f "~A" (car args)))
  36. ((#\d) (number->string (car args)))
  37. ((#\o) (number->string (car args) 8))
  38. ((#\x) (number->string (car args) 16))
  39. ((#\e) (number->string (car args))) ;FIXME
  40. ((#\f) (number->string (car args))) ;FIXME
  41. ((#\g) (number->string (car args))) ;FIXME
  42. ((#\c) (let ((a (car args)))
  43. (if (char? a)
  44. (string a)
  45. (string (integer->char a)))))
  46. ((#\S) (scheme:format #f "~S" (car args)))
  47. (else
  48. (error "Invalid format operation %%%c" (car input))))
  49. output)
  50. #f)))
  51. (case (car input)
  52. ((#\%)
  53. (loop (cdr input) args output #t))
  54. (else
  55. (loop (cdr input) args (cons (car input) output) #f)))))))
  56. (define (message control-string . args)
  57. (display (apply format control-string args))
  58. (newline))