M README.md => README.md +94 -17
@@ 6,10 6,8 @@
<img src="https://raw.githubusercontent.com/janet-lang/janet/master/assets/janet-w200.png" alt="Janet logo" width=200 align="left">
-**Janet** is a functional and imperative programming language and bytecode interpreter. It is a
-Lisp-like language, but lists are replaced
-by other data structures (arrays, tables (hash table), struct (immutable hash table), tuples).
-The language also supports bridging to native code written in C, meta-programming with macros, and bytecode assembly.
+**Janet** is a dynamic language and bytecode interpreter for system scripting, expressive automation, and
+extending programs written in C or C++ with user scripting capabilities.
There is a REPL for trying out the language, as well as the ability
to run script files. This client program is separate from the core runtime, so
@@ 21,14 19,104 @@ If you'd like to financially support the ongoing development of Janet, consider
<br>
+## Examples
+
+See the examples directory for all provided example programs.
+
+### Game of Life
+
+```janet
+# John Conway's Game of Life
+
+(def- window
+ (seq [x :range [-1 2]
+ y :range [-1 2]
+ :when (not (and (zero? x) (zero? y)))]
+ [x y]))
+
+(defn- neighbors
+ [[x y]]
+ (map (fn [[x1 y1]] [(+ x x1) (+ y y1)]) window))
+
+(defn tick
+ "Get the next state in the Game Of Life."
+ [state]
+ (def cell-set (frequencies state))
+ (def neighbor-set (frequencies (mapcat neighbors state)))
+ (seq [coord :keys neighbor-set
+ :let [count (get neighbor-set coord)]
+ :when (or (= count 3) (and (get cell-set coord) (= count 2)))]
+ coord))
+
+(defn draw
+ "Draw cells in the game of life from (x1, y1) to (x2, y2)"
+ [state x1 y1 x2 y2]
+ (def cellset @{})
+ (each cell state (put cellset cell true))
+ (loop [x :range [x1 (+ 1 x2)]
+ :after (print)
+ y :range [y1 (+ 1 y2)]]
+ (file/write stdout (if (get cellset [x y]) "X " ". ")))
+ (print))
+
+# Print the first 20 generations of a glider
+(var *state* '[(0 0) (-1 0) (1 0) (1 1) (0 2)])
+(for i 0 20
+ (print "generation " i)
+ (draw *state* -7 -7 7 7)
+ (set *state* (tick *state*)))
+```
+
+### TCP Echo Server
+
+```janet
+# A simple TCP echo server using the built-in socket networking and event loop.
+
+(defn handler
+ "Simple handler for connections."
+ [stream]
+ (defer (:close stream)
+ (def id (gensym))
+ (def b @"")
+ (print "Connection " id "!")
+ (while (:read stream 1024 b)
+ (printf " %v -> %v" id b)
+ (:write stream b)
+ (buffer/clear b))
+ (printf "Done %v!" id)
+ (ev/sleep 0.5)))
+
+(net/server "127.0.0.1" "8000" handler)
+```
+
+### Windows FFI Hello, World!
+
+```janet
+# Use the FFI to popup a Windows message box - no C required
+
+(ffi/context "user32.dll")
+
+(ffi/defbind MessageBoxA :int
+ [w :ptr text :string cap :string typ :int])
+
+(MessageBoxA nil "Hello, World!" "Test" 0)
+```
+
## Use Cases
Janet makes a good system scripting language, or a language to embed in other programs.
It's like Lua and Guile in that regard. It has more built-in functionality and a richer core language than
-Lua, but smaller than GNU Guile or Python.
+Lua, but smaller than GNU Guile or Python. However, it is much easier to embed and port than these languages.
## Features
+* 600+ functions and macros in the core library
+* Build in socket networking, threading, subprocesses, and more.
+* Parsing Expression Grammars (PEG) engine as a more robust Regex alternative
+* Macros
+* Per-thread event loop for efficient IO (epoll/IOCP/kqueue)
+* Built-in C FFI lets you load existing binaries and run them.
+* Erlang-style supervision trees that integrate with the event loop
* Configurable at build time - turn features on or off for a smaller or more featureful build
* Minimal setup - one binary and you are good to go!
* First-class closures
@@ 38,19 126,12 @@ Lua, but smaller than GNU Guile or Python.
* Mutable and immutable arrays (array/tuple)
* Mutable and immutable hashtables (table/struct)
* Mutable and immutable strings (buffer/string)
-* Macros
* Multithreading
-* Per-thread event loop for efficient evented IO
* Bytecode interpreter with an assembly interface, as well as bytecode verification
* Tail-call optimization
-* Direct interop with C via abstract types and C functions
+* Interface with C via abstract types and C functions
* Dynamically load C libraries
-* Functional and imperative standard library
-* Lexical scoping
-* Imperative programming as well as functional
* REPL
-* Parsing Expression Grammars built into the core library
-* 400+ functions and macros in the core library
* Embedding Janet in other programs
* Interactive environment with detailed stack traces
@@ 240,10 321,6 @@ there is no need for dynamic modules, add the define
See the [Embedding Section](https://janet-lang.org/capi/embedding.html) on the website for more information.
-## Examples
-
-See the examples directory for some example Janet code.
-
## Discussion
Feel free to ask questions and join the discussion on the [Janet Gitter channel](https://gitter.im/janet-language/community).
M meson.build => meson.build +28 -15
@@ 227,21 227,34 @@ docs = custom_target('docs',
# Tests
test_files = [
- 'test/suite0000.janet',
- 'test/suite0001.janet',
- 'test/suite0002.janet',
- 'test/suite0003.janet',
- 'test/suite0004.janet',
- 'test/suite0005.janet',
- 'test/suite0006.janet',
- 'test/suite0007.janet',
- 'test/suite0008.janet',
- 'test/suite0009.janet',
- 'test/suite0010.janet',
- 'test/suite0011.janet',
- 'test/suite0012.janet',
- 'test/suite0013.janet',
- 'test/suite0014.janet'
+ 'test/suite-array.janet',
+ 'test/suite-asm.janet',
+ 'test/suite-boot.janet',
+ 'test/suite-buffer.janet',
+ 'test/suite-capi.janet',
+ 'test/suite-cfuns.janet',
+ 'test/suite-compile.janet',
+ 'test/suite-corelib.janet',
+ 'test/suite-debug.janet',
+ 'test/suite-ev.janet',
+ 'test/suite-ffi.janet',
+ 'test/suite-inttypes.janet',
+ 'test/suite-io.janet',
+ 'test/suite-marsh.janet',
+ 'test/suite-math.janet',
+ 'test/suite-os.janet',
+ 'test/suite-parse.janet',
+ 'test/suite-peg.janet',
+ 'test/suite-pp.janet',
+ 'test/suite-specials.janet',
+ 'test/suite-string.janet',
+ 'test/suite-strtod.janet',
+ 'test/suite-struct.janet',
+ 'test/suite-symcache.janet',
+ 'test/suite-table.janet',
+ 'test/suite-unknown.janet',
+ 'test/suite-value.janet',
+ 'test/suite-vm.janet'
]
foreach t : test_files
test(t, janet_nativeclient, args : files([t]), workdir : meson.current_source_dir())
M src/boot/boot.janet => src/boot/boot.janet +3 -0
@@ 3881,6 3881,9 @@
(defdyn *profilepath*
"Path to profile file loaded when starting up the repl.")
+(compwhen (not (dyn 'os/isatty))
+ (defmacro os/isatty [&] true))
+
(defn cli-main
`Entrance for the Janet CLI tool. Call this function with the command line
arguments as an array or tuple of strings to invoke the CLI interface.`