Login
7 branches 0 tags
Ben (X13/Arch) Added some ARM CI tests 344c2b0 9 months ago 1245 Commits
nujel / binlib / init.nuj
;;; Nujel - Copyright (C) 2020-2021 - Benjamin Vincent Schulenburg
;;; This project uses the MIT license, a copy should be included under /LICENSE
;;;
;;; Initializes the runtime, parses command line arguments and chooses which
;;; module to run.  Essential for a standalone Nujel version, but not needed in
;;; embedded mode.

(def init/executable-name "nujel")
(def init/args #nil)
(def init/options {})
(def init/option-map {})
(def +root-working-dir+ "")
(def *module-path* "")

(defn init args (let*
            (def init/parse-args/eval-next-module #f)
            (def init/parse-args/eval-next #f)
            (def init/parse-args/eval-write-next #f)
            (def init/parse-args/run-repl #t)
            (def init/parse-args/ignore-next #f)
            (set! init/args args)
            (set! +root-working-dir+ (cwd))
            (set! *module-path* (cwd))
            (set! module/loader #nil)
            (module/add-loader module/loader/filesystem)

            (set! init/option-map 'r
                       (fn (option)
                           (tiny-repl)
                         (exit 0)))
            (set! init/option-map 'm
                       (fn (option)
                           (set! init/parse-args/eval-next-module #t)))
            (set! init/option-map 'e
                       (fn (option)
                           (set! init/parse-args/eval-write-next #t)))
            (set! init/option-map 'h
                       (fn (option)
                           (module/main :help #nil)
                         (exit 0)))
            (set! init/option-map 'no-color
                       (fn (option)
                           (import (disable!) :ansi)
                         (set! disable! #t)))
            (set! init/option-map 'color
                       (fn (option)
                           (import (disable!) :ansi)
                         (set! disable! #f)))
            (set! init/option-map 'x
                       (fn (option)
                           (set! init/parse-args/eval-next #t)
                         (set! init/parse-args/run-repl #f)))
            (set! init/option-map :default
                       (fn (option)
                           (set! init/options option #t)))

            (defn init/parse-option (option)
                  ((or (ref init/option-map option)
                       (ref init/option-map :default)) option))

            (defn init/parse-options (options)
                  (if (= (ref options 0) #\-)
                      (init/parse-option (:keyword (cut options 1)))
                      (for-each (map (split options "") :symbol) init/parse-option)))

            (defn init/parse-arg (arg args)
                  (cond (init/parse-args/ignore-next (set! init/parse-args/ignore-next #f))
                        (init/parse-args/eval-next (try print/error
                                                        (eval-in root-closure (cons do (read arg)))
                                                        (set! init/parse-args/eval-next #f)))
                        (init/parse-args/eval-write-next (pfmtln "{:?}" (file/eval arg))
                                                         (exit 0))
                        (init/parse-args/eval-next-module (try (fn (e)
                                                                   (print/error e)
                                                                 (exit 1))
                                                               (when (= (ref arg 0) #\:)
                                                                 (set! arg (:cut arg 1)))
                                                               (def ret (module/main (:keyword arg) (cdr args)))
                                                               (exit 0)))
                        ((= (ref arg 0) #\-) (init/parse-options (:cut arg 1)))
                        (#t (try (fn (e)
                                     (print/error e)
                                   (exit 1))
                                 (file/eval-module arg (cdr args))
                                 (exit 0))
                            (set! init/parse-args/run-repl #f))))

            (defn init/parse-args (args)
                  (if args
                      (do (init/parse-arg (car args) args)
                          (init/parse-args (cdr args)))
                      init/parse-args/run-repl))

            (defn init/bin (args)
                  (try print/error
                       (set! init/executable-name (car args))
                       (when (init/parse-args (cdr args))
                         (module/main :repl #nil))))

            (init/bin args)))