(defmacro (defdoc term . doc) «Define documentation for a top level term. If `term` is a function signature and `doc` is not specified, just the signature will be included in the documentation, without replacing any previously defined. First `doc` argument is supposed to be a string with the description of the term. The following arguments are expected to be optional tag pairings that provide grouping for multiple symbols and "see also" references. Useful in cases where setting the documentation for a term can't (or not preferred to) be done during the definition of said term. One of those reasons could be that the term is a built-in function implemented in C. Examples: (defdoc (func arg (arg2 0)) "Return something about the `arg` and `arg2`. This is a short description. This is the longer description, following the short one. Examples: (func 0) ; ↳ T (func 1 3) ; ↳ NIL" :doc-group stuff :doc-see func2) (defdoc (func arg (:another-variant NIL)))» :doc-group doc (let* {[call (cons? term)] [sym (or (and call (car term)) term)] [callvars (and call (cdr term))] [doc (car (separate-doc-from-body (append doc '(NIL))))]} (if call `(sym-set-doc ',sym ',doc ',callvars) `(sym-set-doc ',sym ',doc)))) (defmacro (doc-group group-name doc) "Define documentation for a group." :doc-group doc `(begin (sym-set-doc (list 'doc 'group ',group-name) ,doc))) (doc-group doc "Writing and reading documentation.") (doc-group prop "Dealing with properties of symbols.") (doc-group compress "Compression.") (defdoc (lz-pack data (level 0)) "Return data compressed using Lempel-Ziv. The data must be an array, returned value will have the same type. The optional `level` is between `0` and `10`. With `level` set to `0` a simple LZSS using hashing will be performed. Levels between `1` and `9` offer a trade-off between time/space and ratio. Level `10` is optimal but very slow." :doc-group compress) (defdoc (lz-unpack data :to destination)) (defdoc (lz-unpack data :size decompressed-bytes) "Return decompressed data previously compressed using lz-pack. Either destination for the decompressed data or the expected size of the decompressed data must be specified. In the latter case a new array is allocated." :doc-group compress) (doc-group rand "Random numbers generation.") (defdoc (rand) "Return a random non-negative fixnum on its maximum range." :doc-group rand) (defdoc (rand-u64) "Return a random integer on interval [0, 2⁶⁴-1]." :doc-group rand) (defdoc (rand-u32) "Return a random integer on interval [0, 2³²-1]." :doc-group rand) (defdoc (rand-f64) "Return a random 64-bit floating point number on interval [0.0, 1.0]." :doc-group rand) (defdoc (rand-f32) "Return a random 32-bit floating pointer number on [0.0, 1.0] interval." :doc-group rand) (doc-group sys "OS-specific functions.") (defdoc +endianness+ "Endianess of the CPU the VM is running on, a constant. Set to either `:big-endian` or `:little-endian`." :doc-group sys) (defdoc *directory-separator* «OS-specific path separator. It is preferred over hardcoded `"/"`, for portability.» :doc-group sys :doc-see *linefeed*) (defdoc *linefeed* «OS-specific _line_ _feed_ value. It is preferred over hardcoded `"\n"`, for portability.» :doc-group sys :doc-see newline :doc-see *directory-separator*) (defdoc +os-name+ «The name of the operating system this StreetLISP VM executable was built for. It's set to a lowercase string and its value is considered "best effort" - it might not always be accurate. Possible values: `"unknown"`, `"plan9"`, `"linux"`, `"openbsd"`, `"netbsd"`, `"dragonflybsd"`, `"freebsd"`, `"haiku"`, `"macosx"`, `"macos"`, `"dos"`.» :doc-group sys :doc-see +os-version+) (defdoc +os-version+ «The "version" of the operating system this StreetLISP VM executable was built for. The availability of the constant and its value depends on the operating system and is only provided for the user to see. No logic should depend on it. Examples: +os-version+ ; ↳ "6.14.5-0-edge" ; Alpine Linux kernel version» :doc-group sys :doc-see +os-name+) (defdoc (os-getenv name) "Return the value of the environment variable `name` or `NIL` if it's not set." :doc-group sys :doc-see os-setenv) (defdoc (os-setenv name value) "Add or replace the value of the environment variable `name` to `value`. If `value` is `NIL`, the variable is deleted from the environment if it exists." :doc-group sys :doc-see os-getenv) (defdoc (exit (status NIL)) «Terminate the process with the specified status. Does not return. The status is expected to be a string in case of an error. Examples: (exit) ; exit with status 0 (nil on Plan 9) (exit "error") ; exit with status 1 ("error" on Plan 9)» :doc-group sys) (defdoc (getpid) "Return the process ID of the StreetLISP VM within the operating system it's running on." :doc-group sys) (doc-group io "Files and I/O functionality.") (defdoc (delete-file path) "Delete the file from the filesystem. Throws an IO error if file does not exist or it failed to be deleted." :doc-group io :doc-see file :doc-see path-exists?) (defdoc (path-exists? path) "Return `T` if `path` exists on the filesystem, `NIL` otherwise." :doc-group io :doc-see file :doc-see delete-file) (defdoc (path-cwd (to NIL)) "Return the full path to the current directory of the process, or change it to the path specified with `to` argument." :doc-group io :doc-see path-exists?) (defdoc (file path (mode #o644) (:read NIL) (:write NIL) (:create NIL) (:truncate NIL) (:append NIL)) "Open a file for I/O. An `io` object is returned. Without any modes specified the file must already exist and is opened in read-only mode. Files are created with the default mode bits #o644." :doc-group io) (defdoc (io? term) "Return `T` if `term` is of `io` type, `NIL` otherwise." :doc-group io :doc-group type) (defdoc (io->str io) "Return the data of the in-memory `io` buffer as a string." :doc-group io) (defdoc (io-eof? io) «Return `T` if `io` is currently in the "end of file" state, `NIL` otherwise.» :doc-group io) (defdoc (eof-object? v) "Return `T` if the argument is `#`, `NIL` otherwise. This object is returned by I/O functions to signal end of file, where applicable." :doc-group io :doc-group type) (defdoc (buffer) "Return an in-memory buffer for I/O, of `io` type. A buffer can be used for both reading and writing at the same time." :doc-group io) (defdoc (assq key lst) "Return a pair of a matching key and the associated value, or `NIL` if none matched. Keys are compared using `eq?`." :doc-group list :doc-see assoc :doc-see assv) (defdoc (memq item lst) "Return the tail of a list beginning with the item, or `NIL` otherwise. List elements are compared to the `item` using `eq?`." :doc-group list :doc-see member :doc-see memv) (defdoc NIL "An empty list. Can be used as the opposite of T in boolean expressions. Examples: (not NIL) ; ↳ T (if NIL 'yes 'no) ; ↳ no (car NIL) ; ↳ NIL (cdr NIL) ; ↳ NIL" :doc-see T) (defdoc T «A boolean "true". Examples: (not T) ; ↳ NIL (if T 'yes 'no) ; ↳ yes» :doc-see NIL) (doc-group string "Strings and runes.") (defdoc (str . terms) «Return concatenation of terms formatted as strings. This is equivalent to `(princ terms…)`, except the string is _returned_, rather than printed. Examples: (str "a" 'b 1 #(0)) ; ↳ "ab1#(0)"» :doc-group string) (defdoc (str-rune s n) «Return the nth rune of the string. Throws an exception if the index `n` is out of bounds. Examples: (str-rune "йцукен" 3) ; ↳ #\к» :doc-group string :doc-see str-sub) (defdoc (str-sub s start (end NIL)) «Return the portion of the string within the specified bounds. The `start` and `end` index by rune. Specifying any index out of bounds of the string will result in an exception thrown. If `end` isn't specified the portion is assumed to begin at `start` until the end of the original string. Examples: (str-sub "hello" 2) ; ↳ "llo" (str-sub "hello" 3 3) ; ↳ "" (str-sub "hello" 2 4) ; ↳ "ll"» :doc-group string :doc-see str-rune) (defdoc (str-utf8? s) «Return `T` if `s` is a valid UTF-8 string, `NIL` otherwise. Examples: (str-utf8? "привет") ; ↳ T (str-utf8? "при\xffвет") ; ↳ NIL» :doc-group string :doc-see str?) (defdoc (str->num s (base NIL)) «Return the number using the radix `base` in the string `s`. Returns `NIL` if the number could not be parsed or there were left-over trailing characters. Examples: (str->num "1.2") ; ↳ 1.2 (str->num "#x123") ; ↳ 291 (str->num "ffff" 16) ; ↳ 65535 (str->num "777" 8) ; ↳ 511» :doc-group string :doc-see num->str) (defdoc (sym term . rest) «Return a symbol with the name being the concatenation of terms formatted as strings. This is equivalent to `(sym (str …))`. Examples: (sym "a" 'b 1) ; ↳ ab1» :doc-group misc :doc-see sym?) (doc-group struct "Declaring and manipulating structures.") (defdoc (defstruct name docs… options… (slot-1 DEFAULT) slot-2 slot-3)) ',sym ',doc ',callvars (defdoc (defstruct name (:type vec) (:named T named-supplied) (:constructor T constructor-supplied) (:conc-name T conc-name-supplied) (:predicate T predicate-supplied) . slots) «Declare a new structure type with the specified name and slots. The default underlying type is a "named" vector (`:type vec`), where the first element is the name of the structure's type, the rest are the keyworded slot values. A list with slot values alone can be used instead by adding `:type list` option. The list will not contain the name of the struct by default, which can be enabled with `:named T` option. As an example, the following declaration generates the default constructor for a structure of three slots, with one of them (`c`) having a non-`NIL` default value and marked as read-only: (defstruct blah "Return stuff." :doc-group stuff a b (c 1 :read-only T)) ; (make-blah (:a NIL) (:b NIL) (:c 1)) ; (blah-a s) ; (blah-b s) ; (blah-c s) ; (blah-a! s new-a) ; (blah-b! s new-b) Slot's options, if any, should be specified after its default value. Supported options are: ; mark the slot as read-only ; its value can be read, but trying to modify it will throw an error … :read-only T The constructor can be changed in several ways: ; disable the constructor altogether (defstruct blah :constructor NIL a b c) ; only change its name (defstruct blah :constructor blargh a b c) ; rename AND avoid using keywords (defstruct blah :constructor (blah a b c) a b c) The option `:conc-name` specifies the slot accessor/setter prefix, which defaults to `structname-`. Prefix can be disabled entirely with `:conc-name NIL`. Slot setters are generated for writable slots by appending `!` (exclamation mark) to the accessor's name. Default predicate can be disabled or its name, which defaults to `structname?`, changed: ; use "blargh?" instead of "blah?" (defstruct blah :predicate blargh? a b c) ; without predicate (defstruct blah :predicate NIL a b c)» :doc-group struct) (defdoc (const? term) "Return `T` if the term refers to a constant, `NIL` otherwise. Constants cannot be modified with `set!`. Trying to do so will result in an exception. Examples: (const? 12345) ; a number ; ↳ T (const? 'const?) ; a function ; ↳ NIL (const? 'pi) ; a mathematical constant ; ↳ T" :doc-group type) (defdoc (bignum? v) "Return `T` if the argument is a bignum, `NIL` otherwise." :doc-group type :doc-group number :doc-see bignum) (defdoc (int? v) "Return `T` if the argument is an integer, `NIL` otherwise." :doc-group type :doc-group number) (defdoc (str? v) "Return `T` if the argument is a string, `NIL` otherwise." :doc-group type :doc-see str :doc-see str-utf8?) (defdoc (gensym? v) "Return `T` if the argument is a gensym, `NIL` otherwise." :doc-group type :doc-see sym? :doc-see sym) (defdoc (ptr? v) "Return `T` if the argument is an abstract pointer, `NIL` otherwise." :doc-group type :doc-group number :doc-see ptr) (defdoc (table? v) "Return `T` if the argument is a table, `NIL` otherwise." :doc-group type :doc-group table :doc-see table) (defdoc (keyword? v) "Return `T` if the argument is a keyword, `NIL` otherwise." :doc-group type) (defdoc most-positive-fixnum "A constant integer closest to positive infinity that can be represented by fixnum type on this particular platform." :doc-group number :doc-see most-negative-fixnum) (defdoc most-negative-fixnum "A constant integer closest to negative infinity that can be represented by fixnum type on this particular platform." :doc-group number :doc-see most-positive-fixnum) (defdoc (fixnum (n 0)) "Construct a fixnum." :doc-group number :doc-see fixnum?) (defdoc (u8 (n 0)) "Construct a 8-bit unsigned number." :doc-group number :doc-see s8) (defdoc (s8 (n 0)) "Construct a 8-bit signed number." :doc-group number :doc-see u8) (defdoc (u16 (n 0)) "Construct a 16-bit unsigned number." :doc-group number :doc-see s16) (defdoc (s16 (n 0)) "Construct a 16-bit signed number." :doc-group number :doc-see u16) (defdoc (u32 (n 0)) "Construct a 32-bit unsigned number." :doc-group number :doc-see s32) (defdoc (s32 (n 0)) "Construct a 32-bit signed number." :doc-group number :doc-see u32) (defdoc (u64 (n 0)) "Construct a 64-bit unsigned number." :doc-group number :doc-see s64) (defdoc (s64 (n 0)) "Construct a 64-bit signed number." :doc-group number :doc-see u64) (defdoc (f32 (n 0.0)) "Construct a 32-bit floating point number." :doc-group number :doc-see f64) (defdoc (f64 (n 0.0)) "Construct a 64-bit floating point number." :doc-group number :doc-see f32) (defdoc (p32 (n 0)) "Construct a 32-bit abstract pointer value." :doc-group number :doc-see p64 :doc-see ptr) (defdoc (p64 (n 0)) "Construct a 64-bit abstract pointer value." :doc-group number :doc-see p32 :doc-see ptr) (defdoc (ptr (n 0)) "Construct an abstract pointer value. The bit width is either 32-bit or 64-bit, depending on the platform the code is executing on. Note: certain arithmetic operations on pointers, such as division and multiplication, will throw an error. This is done on purpose since doing that on pointers rarely makes sense." :doc-group number :doc-see p32 :doc-see p64 :doc-see ptr) (defdoc (rune (n #xfffd)) «Construct a rune from a Unicode code point. Without code point specified, an "invalid" rune is returned.» :doc-group string :doc-see rune?) (defdoc (bignum (n 0)) "Construct a bignum. As opposed to a fixnum, its value is not limited." :doc-group number :doc-see bignum?) (defdoc (floor x) "Return the largest integer that is less than or equal to `x`. Infinity and NaN `floor` to themselves. Examples: (floor 1.2) ; ↳ 1.0 (floor -1.2) ; ↳ -2.0 (floor -5) ; ↳ -5.0" :doc-group number :doc-see ceiling) (defdoc (ceiling x) "Return the smallest integer that is greater than or equal to `x`. Infinity and NaN `ceiling` to themselves. Examples: (ceiling 1.2) ; ↳ 2.0 (ceiling -1.2) ; ↳ -1.0 (ceiling -5) ; ↳ -5.0" :doc-group number :doc-see floor) (defdoc (ash int nbits) "Return the integer shifted by the specified number of bits to the right (negative `nbits`) or left (positive `nbits`). Examples: (ash -3 3) ; ↳ -24 (ash 1 3) ; ↳ 8" :doc-group number) (defdoc (lognot int) "Return the result of bitwise NOT (complement) operation on an integer. Examples: (lognot 0) ; ↳ -1 (lognot #s8(63)) ; ↳ #s8(-64) (lognot #u16(32767)) ; ↳ #u16(32768)" :doc-group number) (defdoc (logior . ints) "Return the result of bitwise OR (inclusive OR) operation on integers. Examples: (logior) ; ↳ 0 (logior 2) ; ↳ 2 (logior 2 3) ; ↳ 3 (logior 2 3 4) ; ↳ 7" :doc-group number) (defdoc (logand . ints) "Return the result of bitwise AND operation on integers. Examples: (logand) ; ↳ 0 (logand 2) ; ↳ 2 (logand 2 3) ; ↳ 2 (logand 2 3 4) ; ↳ 0" :doc-group number) (defdoc (logxor . ints) "Return the result of bitwise XOR (exclusive OR) operation on integers. Examples: (logxor) ; ↳ 0 (logxor 2) ; ↳ 2 (logxor 2 3) ; ↳ 1 (logxor 2 3 4) ; ↳ 5" :doc-group number) (defdoc pi "Mathematical constant π." :doc-group number) (defdoc (acos x) "Return the arc cosine of `x` in radians." :doc-group number) (defdoc (asin x) "Return the arc sine of `x` in radians." :doc-group number) (defdoc (atan x) "Return the arc tangent of `x` in radians." :doc-group number) (defdoc (atan y x) "Return the arc tangent of `y/x` in radians." :doc-group number) (defdoc (cos r) "Return the cosine of `r`, where `r` is given in radians." :doc-group number) (defdoc (sin r) "Return the sine of `r`, where `r` is given in radians." :doc-group number) (defdoc (tan r) "Return the tangent of `r`, where `r` is given in radians." :doc-group number) (defdoc (cosh x) "Return the hyperbolic cosine of `x`." :doc-group number) (defdoc (sinh r) "Return the hyperbolic sine of `x`." :doc-group number) (defdoc (tanh r) "Return the hyperbolic tangent of `x`." :doc-group number) (defdoc (sqrt x) "Return the square root of `x`. Examples: (sqrt 9.0) ; ↳ 3.0" :doc-group number) (defdoc (exp p) "Return the exponential - value of `e` (natural logarithms base) raised to the power of `p`. Examples: (exp 1) ; ↳ 2.71828… ; e¹" :doc-group number) (defdoc (expt x p) "Return the value of `x` raised to the power of `p`. Examples: (expt 3 3) ; cube of 3 ; ↳ 27 (expt 27 (/ 1 3)) ; cube root of 27 ; ↳ 3" :doc-group number) (defdoc (log x (base (exp 1))) "Return the logarithm of `x` in `base`. Default base is `e`, returning natural logarithm of the first argument. Examples: (log 100 10) ; ↳ 2.0 (log 256 2) ; ↳ 8.0 (log (exp 4)) ; ↳ 4.0" :doc-group number) (doc-group vm "VM-related functions.") (defdoc (environment) "Return the list of all bound top level symbols." :doc-group debug :doc-group vm :doc-see print-stack-trace) (defdoc (vm-stats (io *io-out*)) "Print various VM-related information, such as the number of GC calls so far, heap and stack size, etc." :doc-group debug :doc-group vm) (defdoc (gc) "Force a garbage collection run. One does not need to execute this function manually since garbage collection will happen automatically, based on the amount of data allocated." :doc-group vm :doc-see vm-stats) (defdoc (*prompt*) «Function called by REPL to tell the user it's expecting input. The default `*prompt*` function prints `#;> `, which by itself is a commented-out expression, allowing the user to copy-paste the entire line (with the prompt) to re-evaluate.» :doc-group vm :doc-see *interactive*) (defdoc *interactive* «Variable indicating whether VM is running in "interactive" mode (`T`, REPL is active) or not (`NIL`, REPL is not active). Interactive mode can be forced by adding `-i` as the first command line argument.» :doc-group vm :doc-see *prompt*) (defdoc *argv* «The list of command line arguments. If StreetLISP was started in interactive mode without a file specified for execution, `*argv*` will be a list containing just one value - the name of the `sl` executable. Otherwise, the file specified for execution and the rest of the remaining arguments will form the `*argv*` list. StreetLISP's own options, such as `-i` and `-H ...` will be stripped out in any case. Examples: ; $ sl -i -H 12345 *argv* ; ↳ ("sl") ; $ sl script.sl -i abc *argv* ; ↳ ("script.sl" "-i" "abc")» :doc-group vm :doc-see *interactive*) (doc-group array "Arrays and vectors.") (defdoc (copy-vec vec) «Return a copy of the vector with the same elements. No copies of the values themselves are created, the original values are reused. Examples: (def v #vec(1 2 "three")) (def q (copy-vec v)) (eq? v q) ; ↳ NIL (equal? v q) ; ↳ T (map eq? v q) ; ↳ #(T T T)» :doc-group array) (defdoc (arr type . rest) «Construct a packed array containing the specified arguments. The arguments will be coerced to a single `type` which must be a fixed-width number or pointer type, or rune. Examples: (arr 's8 0 1 2) ; ↳ #arr(s8 0 1 2) (arr 'rune 0 1 2) ; ↳ #arr(rune #\nul #\soh #\stx)» :doc-group array :doc-see arr-alloc :doc-see vec) (defdoc *stderr* "Standard error output IO stream." :doc-group io :doc-see *stdout* :doc-see *stdin*) (defdoc *io-err* "Current (default) error output IO stream. Functions may use `*io-err*` for error output, which then can be redirected to a different IO using `with-bindings`." :doc-group io :doc-see *io-out* :doc-see *io-in* :doc-see with-bindings) (defdoc *stdout* "Standard output IO stream." :doc-group io :doc-see *stderr* :doc-see *stdin*) (defdoc *io-out* "Current (default) output IO stream. Functions may use `*io-out*` for output, which then can be redirected to a different IO using either `with-output-to` or (a more general) `with-bindings`." :doc-group io :doc-see *io-err* :doc-see *io-in* :doc-see with-output-to) (defdoc *stdin* "Standard input IO stream." :doc-group io :doc-see *stdout* :doc-see *stderr*) (defdoc *io-in* "Current (default) input IO stream. Functions may use `*io-in*` for input, which then can be redirected from a different IO using either `with-input-from` or (a more general) `with-bindings`." :doc-group io :doc-see *io-out* :doc-see *io-err* :doc-see with-input-from) (doc-group time "Measuring, manipulating and displaying time.") (defdoc (sleep sec) "Halt the StreetLISP VM for the specified duration of time in seconds. Examples: (sleep 0.1) ; sleep for 100ms" :doc-group time) (defdoc (nanoseconds-monotonic) "Return the number of nanoseconds passed since the first call to this function. The first call will always return 0. Examples: (nanoseconds-monotonic) ; ↳ #u64(0) (nanoseconds-monotonic) ; ↳ #u64(47840)" :doc-group time :doc-see time-now) (defdoc (time-now) "Return the number of seconds since Epoch (1970-01-01 00:00:00). This measures the system-wide real (wall-clock) time. Example: (time-now) ; ↳ 1746494461.2773349285" :doc-group time :doc-see nanoseconds-monotonic) (defdoc (time->str sec) «Return the number of seconds since Epoch formatted as time and date. This is the opposite of `str->time`. Examples: (time->str (time-now)) ; ↳ "Tue May 6 03:21:01 CES 2025"» :doc-group time :doc-see str->time :doc-see time-now) (defdoc (str->time str) «Return the number of seconds since Epoch from a time and date formatted as a string. Because the supported format is limited, the returned value will have (at most) precision in full seconds. Examples: (str->time "Tue May 6 03:21:01 CES 2025") ; ↳ 1746494461» :doc-group time :doc-see time->str :doc-see time-now) (defdoc (del! table key) "Remove any existing mapping for `key` and return the table. Examples: (def t #table(a 1 b 2)) (del! t 'c) ; ↳ #table(b 2 a 1) (del! t 'b) ; ↳ #table(a 1) t ; ↳ #table(a 1)" :doc-group table :doc-see has? :doc-see get :doc-see put!) (defdoc (get table key [failed-result]) "Return the value associated with the `key` in the table. If the key isn't in the table then either return the optional `failed-result` argument or (if called without the argument) throw a `key-error` exception. Examples: (def t #table(a 1 b 2)) (get t 'a) ; ↳ 1 (get t 'b NIL) ; ↳ 2 (get t 'c) ; ‼ key not found: a (get t 'c 123) ; ↳ 123" :doc-group table :doc-see has? :doc-see put! :doc-see del!) (defdoc (put! table key value) «Store the value associated with the key and return the table. Any existing value associated with the key will be replaced. Examples: (def t #table(a 1 b 2)) (put! t 'c 3) ; ↳ #table(c 3 b 2 a 1) (put! t 'a "hello") ; ↳ #table(c 3 b 2 a "hello")» :doc-group table :doc-see get :doc-see has? :doc-see del!) (defdoc (has? table key) "Return `T` if the table has a value associated with the key, `NIL` otherwise. Examples: (def t #table(a 1 b 2)) (has? t 'c) ; ↳ NIL (has? t 'a) ; ↳ T" :doc-group table :doc-see get :doc-see put! :doc-see del!) (defdoc (table . rest) "Construct a table from keys from the arguments. Every two arguments are expected to be a key and a value associated with that key. Examples: (table) ; ↳ #table() (table 'a 1 'b 2) ; ↳ #table(a 1 b 2)" :doc-group table :doc-see get :doc-see put!) (defdoc (stacktrace) "Return the current stack trace." :doc-group debug :doc-see print-stack-trace) (defdoc (str-split str (sep " \n\t\v\f") (:trim NIL)) «Return a list of substrings of `str` by splitting at any character in the string `sep`. The splitting characters are removed. By default the string is split on space, line feed (newline), horizontal and vertical tab, and form feed. Trim removes empty strings from the list. Examples: (str-split "hello world") ; ↳ ("hello" "world") (str-split "multiple spaces ") ; ↳ ("multiple" "" "" "spaces" "") (str-split "multiple spaces " :trim T) ; ↳ ("multiple" "spaces") (str-split "too many vowels" "aeiou") ; ↳ ("t" "" " m" "ny v" "w" "ls")» :doc-group string) (defdoc (set-top-level-value! sym expr) "Evaluate the expression and assign the result to the symbol in the top level (global) environment. The use of this function is discouraged. For the usual assignment of values to names it is recommended instead to use `(def …)` and/or `(set! …)`. Examples: (let {[abc 2]} (set-top-level-value! 'abc 123) abc) ; ↳ 2 abc ; ↳ 123" :doc-group misc :doc-see top-level-value :doc-see set!) (defdoc (top-level-value sym) "Return the value bound to the symbol in the top level (global) environment. Examples: (def abc 1) (let {[abc 2]} (cons abc (top-level-value 'abc))) ; ↳ (2 . 1) abc ; ↳ 1" :doc-group misc :doc-see set-top-level-value!) (defdoc (makunbound sym) "Make the symbol unbound. Examples: (def x 1) (bound? 'x) ; ↳ T x ; ↳ 1 (makunbound 'x) (bound? 'x) ; ↳ NIL x ; ‼ eval: variable x has no value" :doc-group misc :doc-see bound?) (defdoc (type-of v) «Return the underlying type of the value. Examples: (type-of 1) ; ↳ fixnum (type-of NIL) ; ↳ null (type-of T) ; ↳ bool (type-of "hello") ; ↳ str (type-of (arr 'u32 0 1 2)) ; ↳ (arr u32)» :doc-group type :doc-see size-of) (defdoc (size-of v) «Return the size of the value in bytes, if applicable. Works only with C integer types, arrays, strings and in-memory buffers. Examples: (size-of "hello") ; ↳ 5 (size-of (arr 'u32 1 2 3)) ; ↳ 12 (def b (buffer)) (io-write b "hello") (size-of b) ; ↳ 5» :doc-group misc :doc-see type-of) (defdoc (io-filename io) «Return the filename of the IO object. Examples: (def f (file "/dev/random")) (io-filename f) ; ↳ "/dev/random" (io-close f) (io-filename f) ; preserved even after it's closed ; ↳ "/dev/random" (io-filename *io-out*) ; ↳ "*stdout*"» :doc-group io :doc-see io-filename!) (defdoc (io-filename! io new-name) «Change the filename of the IO object, return the new filename. Changing the filename does not cause any side effects. The filename is purely informative and does not necessarily reflect the actual path. Examples: (def f (buffer)) (io-filename b) ; ↳ "" (io-filename! b "new name") ; change the filename ; ↳ "new name" (io-filename b) ; ↳ "new name"» :doc-group io :doc-see io-filename) (defdoc (io-line io) «Return the current line number of the IO object. Line number is purely informative and is only being automatically updated with the files opened for reading. If the cursor position is changed via `io-skip` or `io-pos!`, the behavior is undefined.» :doc-group io :doc-see io-column :doc-see io-line!) (defdoc (io-line! io new-line-number) «Change the current line number of the IO object.» :doc-group io :doc-see io-line :doc-see io-column!) (defdoc (io-column io) «Return the current column number of the IO object. Column number is purely informative and is only being automatically updated with the files opened for reading. If the cursor position is changed via `io-skip` or `io-pos!`, the behavior is undefined.» :doc-group io :doc-see io-line :doc-see io-column!) (defdoc (io-column! io new-column-number) «Change the current column number of the IO object.» :doc-group io :doc-see io-column :doc-see io-line!) (defdoc (io-pos io) «Return the current absolute position within the IO object in bytes. Examples: (def f (buffer)) (io-write f "hello, world!") (io-pos f) ; ↳ 13» :doc-group io :doc-see io-pos!) (defdoc (io-pos! io new-position) «Change the current absolute position within the IO object in bytes, return the resulting position. Examples: (def f (buffer)) (io-write f "hello, world!") (io-pos! f 64) ; ↳ 13 (io-pos! f 7) ; ↳ 7 (read f) ; ↳ world!» :doc-group io :doc-see io-pos :doc-see io-skip) (defdoc (io-close io) «Close the IO object. No further operations on the IO object are possible, those will throw an exception if attempted. The only exception is `(io-filename io)`, which might be useful in some cases for debugging purposes. Examples: (def f (file "/dev/random")) (io-read f 'u8) ; ↳ #u8(123) (io-close f) (io-read f 'u8) ; ‼ I/O error: closed file» :doc-group io :doc-see file) (defdoc (io-skip io offset (:end NIL)) «Update the current absolute position within the IO object by the relative offset in bytes, return the resulting absolute position. To specify the position relative to the end of the file, use the optional `:end T` argument with a negative offset. Examples: (def f (buffer)) (io-write f "hello, world!") (io-skip f -6 :end T) ; ↳ 7 (read f) ; ↳ world!» :doc-group io :doc-see io-pos!) (defdoc (io-write io v (endian +endianness+)) «Write the value to the IO object, return the number of bytes written. The value may be a string, a fixed-width number or pointer, a rune or an array. Numerical values may be written in a specific endianness order by setting `endian` to either `:little-endian` or `:big-endian`. Host CPU endianness is used if not specified. When writing a rune or an array of runes, they will be converted and written as an UTF-8 string. Examples: (io-write *stdout* "hello") ; ‼ hello ; ↳ 5 (io-write *stdout* (u32 #x44434241) :little-endian) ; ‼ ABCD ; ↳ 4 (io-write *stdout* #\λ) ; ‼ λ ; ↳ 2 (io-write *stdout* (arr 'rune #\λ #\= #\l #\a #\m #\b #\d #\a)) ; ‼ λ=lambda ; ↳ 9» :doc-group io :doc-see io-read) (defdoc (io-read io type (endian +endianness+))) (defdoc (io-read io type (n NIL) (endian +endianness+)) «Return a value of the specified type by reading it from the IO object. The `type` must specify a fixed-width number, pointer or rune. Numerical values may be read in a specific endianness order by setting `endian` to either `:little-endian` or `:big-endian`. Host CPU endianness is used if not specified. If the parameter `n` is provided, read `n` values of the type, returning an array of the values or a string when `type` is `utf8`. Examples: (io-read f 'utf8 5) ; ↳ "hello" (io-read f 'u32) ; ↳ 57 (io-read f 'u32 3) ; ↳ #arr(u32 0 1 2) (io-read f 'rune 6) ; ↳ #arr(rune #\λ #\a #\m #\b #\d #\a)» :doc-group io :doc-see io-write :doc-see io-read-until) (defdoc (io-read-until io r) "Return a string by reading from the IO object until encountering the delimiting rune `r`. The returned string includes the delimiter." :doc-group io :doc-see io-read) (defdoc (io-copy-until io-dest io-src r) "Copy bytes from the source IO object to the destination until encountering the delimiting rune `r` and return the number of bytes copied. The copied bytes include the delimiter." :doc-group io :doc-see io-copy) (defdoc (io-copy io-dest io-src (n NIL)) "Copy bytes from the source IO object to the destination and return the number of bytes copied. If `n` is provided, copy up to that many bytes." :doc-group io :doc-see io-copy-until) (defdoc (io-buffer-mode io) «Return the output buffering mode of the writable IO. Possible values include: * `NIL` - no buffering, data is written immediately * `:line` - data is written when `#\newline` is encountered * `:block` - data is written when the buffer is full * `:memory` - the IO is an in-memory buffer itself» :doc-group io :doc-see io-buffer-mode!) (defdoc (io-buffer-mode! io) "Changed the output buffering behavior of the writable IO, return the applied value. See `io-buffer-mode` for supported modes." :doc-group io :doc-see io-buffer-mode) (defdoc (io-discard-buffer io) "Discard the contents of the output buffer of the writable IO." :doc-group io :doc-see io-flush :doc-see io-buffer-mode) (defdoc (io-flush io) "Flush the contents of the output buffer to the underlying IO." :doc-group io :doc-see io-discard-buffer :doc-see io-buffer-mode) (defdoc (io-truncate io nbytes) "Truncate the underlying IO object to the specified number of bytes." :doc-group io)