application/octet-stream
•
3.79 KB
•
109 lines
; Nujel - Copyright (C) 2020-2021 - Benjamin Vincent Schulenburg
; This project uses the MIT license, a copy should be included under /LICENSE
[def repl/executable-name "nujel"]
[def repl/parse-args/eval-next #f]
[def repl/parse-args/run-repl #t]
[def repl/options @[]]
[def repl/option-map @[]]
[defun repl/exception-handler [error]
[display/error error]]
[def repl/history #nil]
[defun repl/prompt []
"> "]
[defun repl/wasm [line]
"Evaluate LINE in the wasm context"
[try repl/exception-handler
[def raw [read line]]
[def cexpr [list [compile [cons 'do raw]]]]
[apply root-closure cexpr]]]
[defun repl/readline [ctx]
[def line [readline [repl/prompt]]]
[when [nil? line]
[display "Bye!\r\n"]
[exit 0]]
[readline/history/add line]
[def raw [read line]]
[def expr [cons 'do raw]]
[def cexpr [cons [compile expr]]]
[def result [apply ctx cexpr]]
[set! repl/history [cons line repl/history]]
[println [cat [if [nil? result]
""
[str/write result]]]]]
[defun repl []
[readline/history/load [readline/history/path]]
[while #t
[try repl/exception-handler
[repl/readline root-closure]]
[readline/history/save [readline/history/path]]]]
[defun repl/print-help []
[println [cat [ansi-rainbow "Nujel"] " - A Lisp dialect for games.\n"]]
[println [cat [ansi-green "Usage:"] " nujel [options] [command_string | file]\n"]]
[println [cat [ansi-blue "n"] " - do not load any stdlib"]]
[println [cat [ansi-blue "v"] " - be verbose"]]
[println [cat [ansi-blue "r"] " - eval following file without compilation/expansion"]]
[println [cat [ansi-blue "x"] " - Run the expression following this argument directly"]]]
[defun repl/run-forked* [expr]
[def command [cat repl/executable-name " -x \"" [str/write expr] "\""]]
[popen command]]
[defmacro repl/run-forked [expr]
`[repl/run-forked* ~[list 'quote expr]]]
[tree/set! repl/option-map 'h
[\ [option]
[repl/print-help]
[set! repl/parse-args/run-repl #f]]]
[tree/set! repl/option-map 'x
[\ [option]
[set! repl/parse-args/eval-next #t]
[set! repl/parse-args/run-repl #f]]]
[tree/set! repl/option-map :default
[\ [option]
[tree/set! repl/options option #t]]]
[defun repl/parse-option [option]
[[or [tree/get repl/option-map option]
[tree/get repl/option-map :default]] option]]
[defun repl/parse-options [options]
[if [== [char-at options 0] #\-]
[repl/parse-option [string->keyword [cut options 1]]]
[for-each [map [split options ""] str->sym] repl/parse-option]]]
[defun repl/parse-arg [arg]
[cond [repl/parse-args/eval-next [apply root-closure [cons [compile [cons 'do [read arg]]]]]
[set! repl/parse-args/eval-next #f]]
[[== [char-at arg 0] #\-] [repl/parse-options [string/cut arg 1]]]
[#t [try display/error
[file/eval arg]]
[set! repl/parse-args/run-repl #f]]]]
[defun repl/parse-args [args]
[if args
[do [repl/parse-arg [car args]]
[repl/parse-args [cdr args]]]
repl/parse-args/run-repl]]
[defun repl/init/wasm [args]
[println [cat [ansi-rainbow "Nujel"] " wasm/REPL ready for input"]]]
[defun repl/init/bin [args]
[try repl/exception-handler
[set! repl/executable-name [car args]]
[when [repl/parse-args [cdr args]] [repl]]]]
[defun repl/init args
[if [== System/Architecture 'wasm]
[repl/init/wasm args]
[repl/init/bin args]]]