Janetdocs

3 months ago 1
# This turns the current REPL session (environment) with all bindings, including synced closures, # into a loadable or compilable image. # It is the same as e.g.: `janet -c test.janet test.jimage` after (spit "test.janet" (currenv)) (spit "test.jimage" (make-image (curenv)))make-imageveqqqPlayground# To resume an image's environment: # With this example image: # echo "(def a 1)" > test.janet # janet -c test.janet test.jimage # Now open the REPL: # To enter an image, for continued development or exploration # See: https://janet.zulipchat.com/#narrow/channel/409517-help/topic/Image.20Based.20Development.3F/with/529177765 (defn restore-image [image] (loop [[k v] :pairs image] (put (curenv) k v))) (restore-image (load-image (slurp "test.jimage")))load-imageveqqqPlayground(find |(string/has-prefix? "a" $) ["be" "cat" "art" "apple"]) # => "art" findveqqqPlayground#1) start janet normally, work in the repl, encounter something to debug: (debug) # debug: # in thunk [repl] (tail call) on line 4, column 1 # nil # repl:5:> #2) because the -d flag was missing on start, debug is skipping back out into the repl. now i really DO want to debug here and now, without restarting the vm: (dyn *debug*) # => nil #3) we can just set the flag ourself and thus activate the debugger: (setdyn *debug* :anything_truthy) (debug) # debug: # in thunk [repl] (tail call) on line 2, column 1 # entering debug[1] - (quit) to exit # debug[1]:1:>*debug*kamisoriPlayground(defn knorkulate [a b] (tracev (+ a (* b b )))) # <function knorkulate> (knorkulate 2 34) # trace on line 2, column 1: (+ a (* b b)) is 1158 # 1158tracevkamisoriPlayground(trace +) # <function +> ((trace +) 5 3) # trace (+ 5 3) # 8 (defn knorkulate [a b] ((trace +) a ((trace *) b b ))) # <function knorkulate> (knorkulate 2 34) # trace (* 34 34) # trace (+ 2 1156) # 1158tracekamisoriPlayground# Flatten single level of nested collections (def foo [ [[1 2] [3 4]] [[5 6] [7 8]] ]) (apply array/concat @[] foo) # => @[(1 2) (3 4) (5 6) (7 8)]array/concatmaradPlaygroundtrampoline should work at some callback method which will match these code. most provide callback should be like these! ```c // liba.so void call_mul_at_callback(int i, void (*on_complete) (void*,void*), void* user_data) { // user_data = ctx // work_code int v = i * i + i* i * i << 12 - 5 *i; printf("from janet ffi\n"); on_complete(&i, user_data); printf("FFI CALLBACK COMPLETE\n"); } ``` ```janet (ffi/context "liba.so") (ffi/defbind call-mul-at-callback :void (i :int callback :ptr data :ptr)) (def cb (delay (ffi/trampoline :default))) (call-mul-at-callback 15 (cb) (fn[ptr] (let [args (ffi/read (ffi/struct :int) ptr)] (print (string/format "got value %d from ffi" (first args)))))) ```ffi/trampolinedG94CgPlayground(var enabled false) (toggle enabled) (print enabled) # => truetoggleFuriouZzPlayground# nested iteration (loop [a :in [100 200 300] b :in [1 2 3]] (print (+ a b))) # 101 # 102 # 103 # 201 # 202 # 203 # 301 # 302 # 303looperichaneyPlayground(var x 1) (+= x 2 3 4) # x = 10+=erichaneyPlayground# convert a string to an integer (peg/match '(number :d+) "123") #=> @[123] (first (peg/match '(number :d+) "123")) #=> 123peg/matcherichaneyPlayground(defmacro timeit [& body] # generate unique symbols to use in the macro so they can't conflict with anything used in `body` (with-syms [$t0 $t1] ~(do (def $t0 (os/clock :monotonic :double)) (do ,;body) (def $t1 (os/clock :monotonic :double)) (- $t1 $t0)))) (def time-taken (timeit (os/sleep 0.5))) (printf "Took %.3f seconds" time-taken) with-symsAndriamanitraPlayground(first []) # => nil (first "abc") # => 97firstAndriamanitraPlayground(def arr (array :a [:b :c] :d)) # => @[:a (:b :c) :d] (0 arr) # => :a (1 arr) # => (:b :c) # out-of-bounds access causes an error (try (3 arr) ([err] err)) # => "expected integer key for array in range [0, 3), got 3" # you may use `get` to avoid the error (get arr 3) # => nilarrayAndriamanitraPlayground(= math/-inf (- math/-inf 1)) # => true math/-infsogaiuPlayground# wrap short-fn / | (-> 10 (|(/ $ 2))) # => 5 # also wrap fn (-> 10 ((fn [n] (/ n 2)))) # => 5->sogaiuPlayground# wrap short-fn / | (->> 10 (|(/ $ 2))) # => 5 # also wrap fn (->> 10 ((fn [n] (/ n 2)))) # => 5->>sogaiuPlayground(math/acos 0.3) 1.2661036727795 math/acosbtbytesPlayground new Math.seedrandom('hello.');math/seedrandomMonif2009PlaygroundMath. Seedrandom(3206)math/seedrandomMonif2009Playground# Contrived example returning the variadic arguments passed in. (defmacro example-macro [& args] ~(tuple ,;args)) (example-macro 1 2 3) # => (1 2 3) (def args [1 2 3]) # `apply` is for functions, but there's always `eval`. (assert (= (example-macro 1 2 3) (eval ~(example-macro ,;args))))eval4kbytePlayground# Contrived examples returning the variadic arguments passed in. (defn example-function [& args] args) (defmacro example-macro [& args] ~(tuple ,;args)) (macex '(example-macro 1 2 3)) (assert (= (example-function 1 2 3) (example-macro 1 2 3))) (def args [1 2 3]) # `apply` is for functions, but there's always `eval`. (assert (= (apply example-function args) (eval ~(example-macro ,;args)))) # Same return for both. # => (1 2 3) apply4kbytePlayground(defmacro inner [x] ~(do [,x (* ,x ,x)])) (defmacro outer [n] (map |~(inner ,$0) (range n))) # Hints: # # * Quote the argument. # * Because it's quoted, the argument can have undefined symbols. # * Compare the result of `macex` with `macex1`. # * If needed, print the result with `pp`. # (macex '(outer 10))macex4kbytePlayground# `parse` can decode arbitrary JDN (Janet Data Notation) encoded by `string/format` (def encoded (string/format "%j" @{:a 123 :b "foo" :c @{1 [1.2 2.3 3.4]}})) # => "@{:a 123 :b \"foo\" :c @{1 @[1.2 2.2999999999999998 3.3999999999999999]}}" (parse encoded) # => @{:a 123 :b "foo" :c @{1 @[1.2 2.3 3.4]}}parseCFiggersPlayground(ffi/context "/usr/lib64/libSDL2.so") (ffi/defbind SDL_CreateWindow :ptr [title :string x :int y :int w :int h :int flags :uint32]) (ffi/defbind SDL_Delay :void [ms :uint32]) (ffi/defbind SDL_DestroyWindow :void [window :ptr]) (ffi/defbind SDL_Quit :void []) (def SDL_WINDOW_SHOWN 0x00000004) (defn main [&] (def window (SDL_CreateWindow "Hello world!" 0 0 640 480 SDL_WINDOW_SHOWN)) (SDL_Delay 4000) (SDL_DestroyWindow window) (SDL_Quit)) ffi/defbindAndriamanitraPlayground(print "You are using janet version " janet/version)janet/versionacadiansithPlayground(def [pipe-r pipe-w] (os/pipe)) (ev/spawn # write to the pipe in a separate fiber (for i 0 32000 (def str (string "Hello Janet " i "\n")) (:write pipe-w str)) (:close pipe-w)) (forever (def text (:read pipe-r 4096)) (when (nil? text) (break)) (pp text)) # read a series of strings from the pipe in parallel # to writing to the other side, to avoid the program # from hanging if the pipe is "full" # # see https://github.com/janet-lang/janet/issues/1265os/pipeYohananDiamondPlayground(def [stdin-r stdin-w] (os/pipe)) (def [stdout-r stdout-w] (os/pipe)) # write the input that will be sent to sed (:write stdin-w "hello world 1\nhello world 2") (:close stdin-w) (os/execute @("sed" "s|world|janet|g") :px # the program reads from :in and writes to :out {:in stdin-r :out stdout-w}) (:read stdout-r math/int32-max) # => @"hello janet 1\nhello janet 2" # feed two lines to sed, which replaces "world" # with "janet", and read the modified results backos/executeYohananDiamondPlayground(def [pipe-r pipe-w] (os/pipe)) (:write pipe-w "hello") (:read pipe-r 5) # => @"hello" # send the string "hello" into the writable stream # part and read it back from the readable one os/pipeYohananDiamondPlayground
Read Entire Article