Login
7 branches 0 tags
Ben (X13/Arch) Some comments 27729b7 12 months ago 1242 Commits
nujel / stdlib_modules / repl.nuj
;;; Nujel - Copyright (C) 2020-2021 - Benjamin Vincent Schulenburg
;;; This project uses the MIT license, a copy should be included under /LICENSE
;;;
;;; The REPL implementation, also parses command line arguments and determines
;;; which files to load and whether to start a interactive session.
(import (rainbow) :ansi)

(def *1 #nil)
(def *2 #nil)
(def *3 #nil)
(def line-history #nil)
(def ctx (environment*))

(defn exception-handler (error)
      (print/error error))

(defn push-result (result)
      (set! *3 *2)
      (set! *2 *1)
      (set! *1 result)
      (return result))

(defn cmd/raw (line)
      :export
      (try (fn (err)
               (if (= (car err) :unmatched-opening-bracket)
                   (cmd/raw ctx (cat line (readline "... ")))
                   (throw err)))
           (def expr (read line))
           (when (equal? '() expr)
                 (print "\r")
                 (return))
           (try exception-handler
                (def result (eval-in ctx (cons do expr)))
                (push-result result)
                (println (if (nil? result) "" (string/display result))))))

(defn cmd ()
      (def buf "")
      (def line "")
      (while (not= (trim line) "[/cmd]")
             (set! buf (cat buf line))
             (set! line (readline)))
      (def expr (cons do (read buf)))
      (def result (eval-in ctx expr))
      (push-result result)
      (println (if (nil? result) "" (string/display result))))

(defn prompt ()
      "> ")

(defn read-cmd ()
      (def line (readline (prompt)))
      (cons! line line-history)
      (when (nil? line)
            (println "Adios, cowboy...")
            (exit 0))
      (if (= (trim line) "[cmd]")
          (cmd)
          (cmd/raw line)))

(defn welcome ()
      (println (cat (rainbow "Nujel") " REPL is ready for service!")))

(defn main (args)
      :export
      (welcome)
      (while #t
             (try exception-handler
                  (read-cmd))))