ui.scm 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ;;; Joy -- implementation of the Joy programming language
  2. ;;; Copyright © 2016, 2017 Eric Bavier <bavier@member.fsf.org>
  3. ;;;
  4. ;;; Joy is free software; you can redistribute it and/or modify it under
  5. ;;; the terms of the GNU General Public License as published by the Free
  6. ;;; Software Foundation; either version 3 of the License, or (at your
  7. ;;; option) any later version.
  8. ;;;
  9. ;;; Joy is distributed in the hope that it will be useful, but WITHOUT
  10. ;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. ;;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. ;;; License for more details.
  13. ;;;
  14. ;;; You should have received a copy of the GNU General Public License
  15. ;;; along with Joy. If not, see <http://www.gnu.org/licenses/>.
  16. (define-module (joy ui)
  17. #:use-module (joy config)
  18. #:use-module (ice-9 format)
  19. #:use-module (srfi srfi-1)
  20. #:use-module (srfi srfi-37)
  21. #:use-module (system base compile)
  22. #:use-module (system repl common)
  23. #:use-module (system repl repl)
  24. #:use-module (language joy write)
  25. #:export (joy-main))
  26. (define (show-bug-report-information)
  27. (format #t "
  28. Report bugs to: ~a." %joy-bug-report-address)
  29. (format #t "
  30. ~a home page: <~a>~%" %joy-package-name %joy-home-page-url))
  31. (define (show-version)
  32. "Display version information."
  33. (simple-format #t "~a (~a) ~a~%"
  34. (basename (car (command-line))) %joy-package-name %joy-version)
  35. (simple-format #t "Copyright (C) 2016, 2017 Eric Bavier <bavier@member.fsf.org>~%
  36. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  37. ~a is free software: you are free to change and redistribute it.
  38. There is NO WARRANTY, to the extent permitted by law.
  39. "
  40. %joy-package-name))
  41. (define (show-help)
  42. (display "Usage: joy [OPTION] ... JOY-SCRIPT...")
  43. (newline)
  44. (display "
  45. -h, --help Show this message and exit.")
  46. (display "
  47. -V, --version Show the version string and exit.")
  48. (display "
  49. -I, --include=DIR Add DIR to the list of directories to
  50. search with the \"include\" operator ")
  51. (display "
  52. -S ATOM ..., --stack ATOM ...
  53. Initialize the data stack with ATOM ...,
  54. which may each be a number or string.")
  55. (display "
  56. --debug Start in debug mode.")
  57. (newline)
  58. (show-bug-report-information))
  59. (define (warn-option-not-implemented opt name)
  60. (format (current-error-port) "
  61. joy: warning: option ~a currently not implemented." name))
  62. (define %options
  63. (list (option '(#\h "help") #f #f
  64. (λ _ (show-help) (exit 0)))
  65. (option '(#\V "version") #f #f
  66. (λ _ (show-version) (exit 0)))
  67. (option '(#\I "include") #t #f
  68. (λ (opt name arg result S)
  69. (set! %load-path (cons arg %load-path))
  70. (values result S)))
  71. (option '(#\S "stack") #f #f
  72. (λ (opt name arg result _)
  73. (values result '())))
  74. (option '("debug") #f #f
  75. (λ (opt name arg result S)
  76. (warn-option-not-implemented opt name)
  77. (values result S)))))
  78. (define (compile-files filenames)
  79. "Return a list of compiled file names of the source Joy files in
  80. FILENAMES."
  81. (map
  82. (lambda (filename)
  83. (let ((f (search-path (cons (getcwd) %load-path)
  84. filename '("" ".joy"))))
  85. (if f
  86. (and=> (compiled-file-name f)
  87. (lambda (go)
  88. (compile-file f #:output-file go #:from 'joy)
  89. go))
  90. (begin
  91. (format (current-error-port)
  92. "No such file: ~a~%" filename)
  93. (exit 1)))))
  94. filenames))
  95. (define (compile-and-run programs stack)
  96. (fold (lambda (go S)
  97. (apply (load-compiled go) S))
  98. stack
  99. (compile-files programs)))
  100. (define (repl-welcome repl)
  101. (show-version)
  102. (newline))
  103. (module-set! (resolve-module '(system repl common))
  104. 'repl-welcome repl-welcome)
  105. (define (simple-interpret string)
  106. "Interpret simple Joy atoms."
  107. (cond ((string->number string) => identity)
  108. (else (string->list string))))
  109. (define (joy-main . args)
  110. (let ((repl (make-repl 'joy-repl)))
  111. (repl-option-set! repl 'print (lambda (repl val) (write-joy val)))
  112. (repl-option-set! repl 'value-history #f)
  113. (call-with-values
  114. (lambda () (args-fold (cdr args)
  115. %options
  116. (λ (opt name arg . rest)
  117. (error "~A: unrecognized option~%"
  118. name))
  119. (λ (arg result S)
  120. (if S
  121. (values result (cons arg S))
  122. (values (cons arg result) S)))
  123. '() #f))
  124. (lambda (programs stack)
  125. (let ((S (map simple-interpret (or stack '()))))
  126. (if (null? programs)
  127. (parameterize (((@@ (language joy-repl spec) %joy-stack) S))
  128. (run-repl repl))
  129. (compile-and-run (reverse programs) S)))))))