mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-30 23:23:07 +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:
		
							
								
								
									
										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(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose