mirror of
https://github.com/janet-lang/janet
synced 2025-01-10 23:50:26 +00:00
Move init.janet into cli-main in boot.janet
This makes it easier to get the CLI functionality when embedding Janet, although the main reason is the init script is now pre-compiled to bytecode when generating the boot image.
This commit is contained in:
parent
b2263ed5b5
commit
0d16b9e1a1
4
Makefile
4
Makefile
@ -147,7 +147,7 @@ build/core_image.c: build/janet_boot
|
||||
##########################################################
|
||||
|
||||
JANET_CORE_OBJECTS=$(patsubst src/%.c,build/%.o,$(JANET_CORE_SOURCES)) build/core_image.o
|
||||
JANET_MAINCLIENT_OBJECTS=$(patsubst src/%.c,build/%.o,$(JANET_MAINCLIENT_SOURCES)) build/init.gen.o
|
||||
JANET_MAINCLIENT_OBJECTS=$(patsubst src/%.c,build/%.o,$(JANET_MAINCLIENT_SOURCES))
|
||||
|
||||
# Compile the core image generated by the bootstrap build
|
||||
build/core_image.o: build/core_image.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS)
|
||||
@ -204,8 +204,6 @@ emscripten: $(JANET_EMTARGET)
|
||||
build/xxd: tools/xxd.c
|
||||
$(CC) $< -o $@
|
||||
|
||||
build/init.gen.c: src/mainclient/init.janet build/xxd
|
||||
build/xxd $< $@ janet_gen_init
|
||||
build/webinit.gen.c: src/webclient/webinit.janet build/xxd
|
||||
build/xxd $< $@ janet_gen_webinit
|
||||
build/boot.gen.c: src/boot/boot.janet build/xxd
|
||||
|
@ -40,14 +40,10 @@ link /nologo /out:build\xxd.exe build\xxd.obj
|
||||
@if errorlevel 1 goto :BUILDFAIL
|
||||
|
||||
@rem Generate the embedded sources
|
||||
build\xxd.exe src\mainclient\init.janet build\init.gen.c janet_gen_init
|
||||
@if errorlevel 1 goto :BUILDFAIL
|
||||
build\xxd.exe src\boot\boot.janet build\boot.gen.c janet_gen_boot
|
||||
@if errorlevel 1 goto :BUILDFAIL
|
||||
|
||||
@rem Build the generated sources
|
||||
%JANET_COMPILE% /Fobuild\mainclient\init.gen.obj build\init.gen.c
|
||||
@if errorlevel 1 goto :BUILDFAIL
|
||||
%JANET_COMPILE% /Fobuild\boot\boot.gen.obj build\boot.gen.c
|
||||
@if errorlevel 1 goto :BUILDFAIL
|
||||
|
||||
|
@ -83,7 +83,6 @@ gen = generator(xxd,
|
||||
output : '@BASENAME@.gen.c',
|
||||
arguments : ['@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@'])
|
||||
boot_gen = gen.process('src/boot/boot.janet', extra_args: 'janet_gen_boot')
|
||||
init_gen = gen.process('src/mainclient/init.janet', extra_args: 'janet_gen_init')
|
||||
|
||||
# Order is important here, as some headers
|
||||
# depend on other headers for the amalg target
|
||||
@ -185,14 +184,14 @@ else
|
||||
extra_cross_cflags = []
|
||||
endif
|
||||
|
||||
janet_mainclient = executable('janet', core_src, core_image, init_gen, mainclient_src,
|
||||
janet_mainclient = executable('janet', core_src, core_image, mainclient_src,
|
||||
include_directories : incdir,
|
||||
dependencies : [m_dep, dl_dep],
|
||||
c_args : extra_native_cflags,
|
||||
install : true)
|
||||
|
||||
if meson.is_cross_build()
|
||||
janet_nativeclient = executable('janet-native', core_src, core_image, init_gen, mainclient_src,
|
||||
janet_nativeclient = executable('janet-native', core_src, core_image, mainclient_src,
|
||||
include_directories : incdir,
|
||||
dependencies : [m_dep, dl_dep],
|
||||
c_args : extra_cross_cflags,
|
||||
@ -216,7 +215,7 @@ amalg = custom_target('amalg',
|
||||
command : [janet_nativeclient, '@INPUT@'])
|
||||
|
||||
# Amalgamated client
|
||||
janet_amalgclient = executable('janet-amalg', amalg, init_gen, mainclient_src,
|
||||
janet_amalgclient = executable('janet-amalg', amalg, mainclient_src,
|
||||
include_directories : incdir,
|
||||
dependencies : [m_dep, dl_dep],
|
||||
build_by_default : false)
|
||||
|
@ -1906,6 +1906,8 @@
|
||||
(def ret (bad-compile x y z))
|
||||
(if exit-on-error (os/exit 1))
|
||||
ret)
|
||||
(unless f
|
||||
(error (string "could not find file " path)))
|
||||
(run-context {:env env
|
||||
:chunks chunks
|
||||
:on-parse-error bp
|
||||
@ -2054,6 +2056,125 @@ _fiber is bound to the suspended fiber
|
||||
(put _env 'env-walk nil)
|
||||
(put _env '_env nil)
|
||||
|
||||
###
|
||||
###
|
||||
### CLI Tool Main
|
||||
###
|
||||
###
|
||||
|
||||
(defn cli-main
|
||||
"Entrance for the Janet CLI tool. Call this functions with the command line
|
||||
arguments as an array or tuple of strings to invoke the CLI interface."
|
||||
[args]
|
||||
(setdyn :args args)
|
||||
|
||||
(var *should-repl* false)
|
||||
(var *no-file* true)
|
||||
(var *quiet* false)
|
||||
(var *raw-stdin* false)
|
||||
(var *handleopts* true)
|
||||
(var *exit-on-error* true)
|
||||
(var *colorize* true)
|
||||
(var *compile-only* false)
|
||||
|
||||
(if-let [jp (os/getenv "JANET_PATH")] (setdyn :syspath jp))
|
||||
(if-let [jp (os/getenv "JANET_HEADERPATH")] (setdyn :headerpath jp))
|
||||
|
||||
# Flag handlers
|
||||
(def handlers :private
|
||||
{"h" (fn [&]
|
||||
(print "usage: " (dyn :executable "janet") " [options] script args...")
|
||||
(print
|
||||
`Options are:
|
||||
-h : Show this help
|
||||
-v : Print the version string
|
||||
-s : Use raw stdin instead of getline like functionality
|
||||
-e code : Execute a string of janet
|
||||
-r : Enter the repl after running all scripts
|
||||
-p : Keep on executing if there is a top level error (persistent)
|
||||
-q : Hide prompt, logo, and repl output (quiet)
|
||||
-k : Compile scripts but do not execute
|
||||
-m syspath : Set system path for loading global modules
|
||||
-c source output : Compile janet source code into an image
|
||||
-n : Disable ANSI color output in the repl
|
||||
-l path : Execute code in a file before running the main script
|
||||
-- : Stop handling options`)
|
||||
(os/exit 0)
|
||||
1)
|
||||
"v" (fn [&] (print janet/version "-" janet/build) (os/exit 0) 1)
|
||||
"s" (fn [&] (set *raw-stdin* true) (set *should-repl* true) 1)
|
||||
"r" (fn [&] (set *should-repl* true) 1)
|
||||
"p" (fn [&] (set *exit-on-error* false) 1)
|
||||
"q" (fn [&] (set *quiet* true) 1)
|
||||
"k" (fn [&] (set *compile-only* true) (set *exit-on-error* false) 1)
|
||||
"n" (fn [&] (set *colorize* false) 1)
|
||||
"m" (fn [i &] (setdyn :syspath (get args (+ i 1))) 2)
|
||||
"c" (fn [i &]
|
||||
(def e (dofile (get args (+ i 1))))
|
||||
(spit (get args (+ i 2)) (make-image e))
|
||||
(set *no-file* false)
|
||||
3)
|
||||
"-" (fn [&] (set *handleopts* false) 1)
|
||||
"l" (fn [i &]
|
||||
(import* (get args (+ i 1))
|
||||
:prefix "" :exit *exit-on-error*)
|
||||
2)
|
||||
"e" (fn [i &]
|
||||
(set *no-file* false)
|
||||
(eval-string (get args (+ i 1)))
|
||||
2)})
|
||||
|
||||
(defn- dohandler [n i &]
|
||||
(def h (get handlers n))
|
||||
(if h (h i) (do (print "unknown flag -" n) ((get handlers "h")))))
|
||||
|
||||
(def- safe-forms {'defn true 'defn- true 'defmacro true 'defmacro- true})
|
||||
(def- importers {'import true 'import* true 'use true 'dofile true 'require true})
|
||||
(defn- evaluator
|
||||
[thunk source env where]
|
||||
(if *compile-only*
|
||||
(when (tuple? source)
|
||||
(cond
|
||||
(safe-forms (source 0)) (thunk)
|
||||
(importers (source 0))
|
||||
(do
|
||||
(let [[l c] (tuple/sourcemap source)
|
||||
newtup (tuple/setmap (tuple ;source :evaluator evaluator) l c)]
|
||||
((compile newtup env where))))))
|
||||
(thunk)))
|
||||
|
||||
# Process arguments
|
||||
(var i 0)
|
||||
(def lenargs (length args))
|
||||
(while (< i lenargs)
|
||||
(def arg (get args i))
|
||||
(if (and *handleopts* (= "-" (string/slice arg 0 1)))
|
||||
(+= i (dohandler (string/slice arg 1 2) i))
|
||||
(do
|
||||
(set *no-file* false)
|
||||
(dofile arg :prefix "" :exit *exit-on-error* :evaluator evaluator)
|
||||
(set i lenargs))))
|
||||
|
||||
(when (and (not *compile-only*) (or *should-repl* *no-file*))
|
||||
(if-not *quiet*
|
||||
(print "Janet " janet/version "-" janet/build " Copyright (C) 2017-2019 Calvin Rose"))
|
||||
(defn noprompt [_] "")
|
||||
(defn getprompt [p]
|
||||
(def [line] (parser/where p))
|
||||
(string "janet:" line ":" (parser/state p :delimiters) "> "))
|
||||
(def prompter (if *quiet* noprompt getprompt))
|
||||
(defn getstdin [prompt buf]
|
||||
(file/write stdout prompt)
|
||||
(file/flush stdout)
|
||||
(file/read stdin :line buf))
|
||||
(def getter (if *raw-stdin* getstdin getline))
|
||||
(defn getchunk [buf p]
|
||||
(getter (prompter p) buf))
|
||||
(def onsig (if *quiet* (fn [x &] x) nil))
|
||||
(setdyn :pretty-format (if *colorize* "%.20Q" "%.20q"))
|
||||
(setdyn :err-color (if *colorize* true))
|
||||
(repl getchunk onsig)))
|
||||
|
||||
###
|
||||
###
|
||||
### Bootstrap
|
||||
|
@ -1,111 +0,0 @@
|
||||
# Copyright 2017-2019 (C) Calvin Rose
|
||||
|
||||
(do
|
||||
|
||||
(var *should-repl* false)
|
||||
(var *no-file* true)
|
||||
(var *quiet* false)
|
||||
(var *raw-stdin* false)
|
||||
(var *handleopts* true)
|
||||
(var *exit-on-error* true)
|
||||
(var *colorize* true)
|
||||
(var *compile-only* false)
|
||||
|
||||
(if-let [jp (os/getenv "JANET_PATH")] (setdyn :syspath jp))
|
||||
(if-let [jp (os/getenv "JANET_HEADERPATH")] (setdyn :headerpath jp))
|
||||
(def args (dyn :args))
|
||||
|
||||
# Flag handlers
|
||||
(def handlers :private
|
||||
{"h" (fn [&]
|
||||
(print "usage: " (get args 0) " [options] script args...")
|
||||
(print
|
||||
`Options are:
|
||||
-h : Show this help
|
||||
-v : Print the version string
|
||||
-s : Use raw stdin instead of getline like functionality
|
||||
-e code : Execute a string of janet
|
||||
-r : Enter the repl after running all scripts
|
||||
-p : Keep on executing if there is a top level error (persistent)
|
||||
-q : Hide prompt, logo, and repl output (quiet)
|
||||
-k : Compile scripts but do not execute
|
||||
-m syspath : Set system path for loading global modules
|
||||
-c source output : Compile janet source code into an image
|
||||
-n : Disable ANSI color output in the repl
|
||||
-l path : Execute code in a file before running the main script
|
||||
-- : Stop handling options`)
|
||||
(os/exit 0)
|
||||
1)
|
||||
"v" (fn [&] (print janet/version "-" janet/build) (os/exit 0) 1)
|
||||
"s" (fn [&] (set *raw-stdin* true) (set *should-repl* true) 1)
|
||||
"r" (fn [&] (set *should-repl* true) 1)
|
||||
"p" (fn [&] (set *exit-on-error* false) 1)
|
||||
"q" (fn [&] (set *quiet* true) 1)
|
||||
"k" (fn [&] (set *compile-only* true) (set *exit-on-error* false) 1)
|
||||
"n" (fn [&] (set *colorize* false) 1)
|
||||
"m" (fn [i &] (setdyn :syspath (get args (+ i 1))) 2)
|
||||
"c" (fn [i &]
|
||||
(def e (dofile (get args (+ i 1))))
|
||||
(spit (get args (+ i 2)) (make-image e))
|
||||
(set *no-file* false)
|
||||
3)
|
||||
"-" (fn [&] (set *handleopts* false) 1)
|
||||
"l" (fn [i &]
|
||||
(import* (get args (+ i 1))
|
||||
:prefix "" :exit *exit-on-error*)
|
||||
2)
|
||||
"e" (fn [i &]
|
||||
(set *no-file* false)
|
||||
(eval-string (get args (+ i 1)))
|
||||
2)})
|
||||
|
||||
(defn- dohandler [n i &]
|
||||
(def h (get handlers n))
|
||||
(if h (h i) (do (print "unknown flag -" n) ((get handlers "h")))))
|
||||
|
||||
(def- safe-forms {'defn true 'defn- true 'defmacro true 'defmacro- true})
|
||||
(def- importers {'import true 'import* true 'use true 'dofile true 'require true})
|
||||
(defn- evaluator
|
||||
[thunk source env where]
|
||||
(if *compile-only*
|
||||
(when (tuple? source)
|
||||
(cond
|
||||
(safe-forms (source 0)) (thunk)
|
||||
(importers (source 0))
|
||||
(do
|
||||
(let [[l c] (tuple/sourcemap source)
|
||||
newtup (tuple/setmap (tuple ;source :evaluator evaluator) l c)]
|
||||
((compile newtup env where))))))
|
||||
(thunk)))
|
||||
|
||||
# Process arguments
|
||||
(var i 0)
|
||||
(def lenargs (length args))
|
||||
(while (< i lenargs)
|
||||
(def arg (get args i))
|
||||
(if (and *handleopts* (= "-" (string/slice arg 0 1)))
|
||||
(+= i (dohandler (string/slice arg 1 2) i))
|
||||
(do
|
||||
(set *no-file* false)
|
||||
(dofile arg :prefix "" :exit *exit-on-error* :evaluator evaluator)
|
||||
(set i lenargs))))
|
||||
|
||||
(when (and (not *compile-only*) (or *should-repl* *no-file*))
|
||||
(if-not *quiet*
|
||||
(print "Janet " janet/version "-" janet/build " Copyright (C) 2017-2019 Calvin Rose"))
|
||||
(defn noprompt [_] "")
|
||||
(defn getprompt [p]
|
||||
(def [line] (parser/where p))
|
||||
(string "janet:" line ":" (parser/state p :delimiters) "> "))
|
||||
(def prompter (if *quiet* noprompt getprompt))
|
||||
(defn getstdin [prompt buf]
|
||||
(file/write stdout prompt)
|
||||
(file/flush stdout)
|
||||
(file/read stdin :line buf))
|
||||
(def getter (if *raw-stdin* getstdin getline))
|
||||
(defn getchunk [buf p]
|
||||
(getter (prompter p) buf))
|
||||
(def onsig (if *quiet* (fn [x &] x) nil))
|
||||
(setdyn :pretty-format (if *colorize* "%.20Q" "%.20q"))
|
||||
(setdyn :err-color (if *colorize* true))
|
||||
(repl getchunk onsig)))
|
@ -31,9 +31,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern const unsigned char *janet_gen_init;
|
||||
extern int32_t janet_gen_init_size;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i, status;
|
||||
JanetArray *args;
|
||||
@ -83,13 +80,15 @@ int main(int argc, char **argv) {
|
||||
args = janet_array(argc);
|
||||
for (i = 1; i < argc; i++)
|
||||
janet_array_push(args, janet_cstringv(argv[i]));
|
||||
janet_table_put(env, janet_ckeywordv("args"), janet_wrap_array(args));
|
||||
|
||||
/* Save current executable path to (dyn :executable) */
|
||||
janet_table_put(env, janet_ckeywordv("executable"), janet_cstringv(argv[0]));
|
||||
|
||||
/* Run startup script */
|
||||
status = janet_dobytes(env, janet_gen_init, janet_gen_init_size, "init.janet", NULL);
|
||||
Janet mainfun, out;
|
||||
janet_resolve(env, janet_csymbol("cli-main"), &mainfun);
|
||||
Janet mainargs[1] = { janet_wrap_array(args) };
|
||||
status = janet_pcall(janet_unwrap_function(mainfun), 1, mainargs, &out, NULL);
|
||||
|
||||
/* Deinitialize vm */
|
||||
janet_deinit();
|
||||
|
Loading…
Reference in New Issue
Block a user