FreeBSD Manual Pages
FTH(1) General Commands Manual FTH(1) NAME fth -- Forth script and extension language SYNOPSIS fth [-DdQqrv] [-C so-lib-path] [-E eval] [-e eval] [-f init-file] [-I fs-path] [-S "lib init"] [-s file] [file ...] fth [-alnp] [-e eval] [-F fs] [-i[suffix]] [file ...] fth -V DESCRIPTION This is the manual page for the interactive and script processing Forth interpreter fth based on John Sadler's Ficl, Forth-inspired command language. This manual page provides information for running and pro- gramming fth in a Unix command line environment, see libfth(3) for Forth as an extension language. The fth interpreter can also be used as a command line filter and process files in-place. The options -a, -e, -i, -l, -n, -p and in ad- dition -F are provided for this purpose, see "EXAMPLES" below. Argument List Processing -a Starts an implicit loop action on standard input or files given on command line and splits every line to array *farray* and sets single fields of the line to corresponding *1* ... *9* variables before processing -e eval. The split string is the field separator *fs*, default a space. Can be combined with -n, -p and in-place option -i[suffix]. See also options -F and -l. -C path Adds path to the front of *load-lib-path* where C extension libraries (*.so) reside, multiple calls are possible. -D Shows backtrace and exits with return code 1 (EXIT_FAILURE) if an exception was found while evaluating the initialization file, running a script, loading additional source files, or evaluating strings from the command line. -d Sets global variable *fth-debug* to #t. -E eval Evaluates eval and stays in an interactive read-eval-print- loop. Multiple calls are possible, see also -e. -e eval Evaluates eval and exits. Multiple calls are possible. The last or only -e eval can be considered between lambda: ( -- ) eval ; and is in compile state! If multiple calls appear, all but the last are in interpret state. For example, the following renames config.h to config.h.orig and reads it line by line. If a line occurs containing #define HAVE_COMPLEX_DOUBLE replaces entire line with /* #undef HAVE_COMPLEX_DOUBLE */ otherwise writes the original line to config.h. The first -e sets the global Forth variable reg to a Regexp object, the second -e uses this variable for testing. The eval of the first -e is evaluated in interpret state before reading the file while the eval of the second -e is evaluated in compile state in a nameless lambda: (--) eval ; word while reading the file line by line: % fth -ni.orig \ -e '/#define HAVE_COMPLEX_DOUBLE/ value reg' \ -e 'reg *line* re= if \ "/* #undef HAVE_COMPLEX_DOUBLE */\n" \ else \ *line* \ then' config.h -F fs Sets the global variable *fs* to the field separator fs used by option -a. See also implicit loop and in-place options -i, -l, -n and -p. -f file Takes initialization file instead of ~/.fthrc. Use -Q to prevent loading initialization files. -I path Adds path to the front of *load-path* where Forth script files (*.fs) reside, multiple calls are possible. -i[suffix] Starts an implicit loop action on files given on command line and processes -e eval on each line in-place. If no suffix was specified, writes to the same file after processing, oth- erwise copies original to the backup file before reading it. See option -e above for an example and see also implicit loop options -a, -F, -l, -n -p. Note: There are no spaces allowed between -i and suffix if suffix was specified! -l Removes line ending `\n' when used with implicit loop options -n, -p and in-place option -i[suffix]. See also options -a and -F. -n Starts an implicit loop action on standard input or files given on command line and processes -e eval on each line while not echoing every *line* to standard output. See also implicit loop and in-place options -a, -F, -i, -l and -p. -p Starts an implicit loop action on standard input or files given on command line and processes -e eval on each line while echoing every *line* unaltered to standard output. See also implicit loop and in-place options -a, -F, -i, -l and -n. -Q The global and local initialization files are not loaded. -q Sets global variable *fth-verbose* to #f. -r Starts a conventional Forth-like session with the data stack left untouched after pressing <Return>. Normally the data stack is printed and cleared but -r changes this behavior to something like a read-eval-loop instead of a read-eval-print-loop. -S "lib init" Loads C extension library lib and calls the initialization function init. lib and init must be enclosed in quotes. -S "dbm Init_dbm" Multiple calls are possible. -s file Evaluates file as a Forth script and exits after processing. No initialization file is read and the global Forth variables *argc* and *argv* are set and filled with the count and com- mand line options appearing after -s file. This must be the last option given to the fth interpreter. Options after that are taken as script options and can be used for getopt pro- cessing in the script. This makes it possible to create hash bang scripts with a first line like #! /usr/pkg/bin/fth -s Note the space after #!. It's a Forth word starting a com- ment and must be separated by at least one space. % cat hello-world.fth #! /usr/pkg/bin/fth -s ." Hello, World!" cr -V Displays version information and exits. -v Sets global variable *fth-verbose* to #t. file ... file ... will be loaded as Forth source file, more than one can be present. If file is `-', reads from standard input, see "EXAMPLES" below. Stack Effect The documentation shows the stack effect of words in this way: ( a b c -- d ) The left side of the double dash shows the stack required by the word, the ride side shows what the word left on stack. One or both sides may be empty. ( -- ) ( a -- ) ( -- a ) Parse words have the following kind of stack effect: ( "name" -- ) Parse words read their input from the input stream in contrary to regu- lar words which expect their input on stack; "name" is expected after the word. As a parse word example, fth has help ( "name" -- ) which is used like help apropos This word takes its arguments from the input stream, in this case apropos, and tries to find its help strings, which are returned if found. There is another kind of words, so called procs (see in subsection "Procs And Xts", word "<{"), they may show a slightly different stack effect because they can have keyword and optional arguments and may look like this: ( :key host "localhost" :optional port 13 -- str ) Local variables are automatically defined, host is set to string "lo- calhost" and port to integer 13, the return value of this example is a String object. You may specify these with :host "pumpkin" and :port 79 before calling the word. For example, ${prefix}/share/fth/fth-lib/net.fs contains finger ( :key host "localhost" :optional user getlogin -- str ) which can be used in either of these forms: finger \ default values for host and user "yorick" finger \ default value for host :host "pumpkin" finger \ default value for user "yorick" :host "pumpkin" finger Forth Variables *0* Entire current input line when implicit loop and in-place processing takes place. *1* ... *9* If -a was specified when implicit loop and in-place process- ing takes place, these are the corresponding first nine sin- gle elements of *farray*. .*0* Prints entire current input line when implicit loop and in- place processing takes place. .*1* ... .*9* If -a was specified when implicit loop and in-place process- ing takes place, prints the corresponding single elements of *farray* with the string of *ofs* attached, default a single space. *argc* Number of arguments in *argv*. *argv* List of command line arguments. *exception-list* Array containing all exceptions. *farray* If -a was specified when implicit loop and in-place process- ing takes place, auto-split array of current input line. *features* Array containing all features. *filename* Returns currently processed Forth filename, see also "*lineno*". *fname* Current filename for implicit loop and in-place processing. *fnr* Input record number for implicit loop and in-place process- ing. This is the line number in the current file, starting from 0 for every file. *fs* Input field separator for implicit loop and in-place process- ing, default one space. *fth-debug* If #t, displays more diagnostic output. *fth-verbose* If #t, displays more output. *key* Contains current value from any object in map ... end-map loops. *last-exception* Contains last raised exception. *line* String of entire current line for implicit loop and in-place processing. *lineno* Returns currently processed line number in current Forth file, see also "*filename*". *load-lib-path* Array of directories where fth searches for C extension li- braries (*.so). *load-path* Array of directories where fth searches for Forth script files (*.fs). *loaded-files* Array of already loaded files. *nr* Input record number for implicit loop and in-place process- ing. This is the accumulated line number for all files processed so far. *ofs* Output field separator for implicit loop and in-place pro- cessing, default one space. *re* Array containing the last regexp match. *re-syntax-options* Regexp syntax option, default REG_EXTENDED. *re0* Last entire match of regexp search. *re1* ... *re9* Last subexpression matches of regexp search. Hook Variables fth calls five hooks if they are not empty: before and after loading source files and in interactive mode before starting and after ending the repl as well as every time before showing the prompt. before-load-hook ( filename -- f ) Called before loading filename. If hook returns #f, filename won't be loaded. before-load-hook lambda: <{ fname -- f }> "\\ loading %s\n" #( fname ) fth-print #t ; add-hook! after-load-hook ( filename -- ) Called after loading filename and updating global variable *loaded-files*. after-load-hook lambda: <{ fname -- }> "\\ %s loaded\n" #( fname ) fth-print ; add-hook! before-repl-hook ( -- ) Called after initializing the tecla(7) command-line editing library but before starting the repl. A predefined hook showing some help lines can be replaced by your own message: before-repl-hook reset-hook! before-repl-hook lambda: <{ -- }> ." \" cr ." \ Starting FTH on " date .string ." !" cr ." \" cr ; add-hook! after-repl-hook ( history -- ) Called after leaving the repl and writing the history file but before leaving the program. Its only argument is the history filename. You may manipulate the history data entries. One history entry consists of two lines: a time stamp preceded by a Forth comment backslash and the actual history line: \ 20201116031253 0 "mail" .getservbyname after-repl-hook lambda: <{ history -- }> \ Remove duplicates from history file. history readlines array-reverse! { hary } #() "" "" { nhary hline tline } hary array-length 0 ?do hary i array-ref to hline hary i 1+ array-ref to tline nhary hline array-member? unless nhary hline array-unshift tline array-unshift drop then 2 +loop history nhary writelines ; add-hook! before-prompt-hook ( prompt pos -- new-prompt ) Called before printing a new prompt to customize the output of it. prompt is the old prompt and pos the current history position. The return value is the prompt argument for the next hook procedure if any: before-prompt-hook lambda: <{ prompt pos -- new-prompt }> "fth (%d) ok " '( pos ) string-format ; add-hook! Or with standout and bold mode, see gl_prompt_style(3) and "Tecla Variables" below for *promptstyle*: #t to *promptstyle* before-prompt-hook lambda: <{ prompt pos -- new-prompt }> "%%Sfth (%d)%%s %%Bok%%b " '( pos ) string-format ; add-hook! The Command-line Editor Command-line editing similar to tcsh(1) is handled by the tecla(7) li- brary if installed. Predefined bindings exist for those similar to vi(1) and emacs. The default editing mode is emacs-mode. You can switch from emacs-mode to vi-mode via M-^V and from vi-mode to emacs- mode via M-^E. To start in vi-mode, put a line like edit-mode vi in your ~/.teclarc file. A history of the last command-lines can be listed with ^Xh, the last 10 history entries can be listed with M-10^Xh. The Tab-key or ^I initiates word completion. If the Forth dictionary has more than one entry starting with characters before the cursor, show all, if only one definition exists, completes it and adds a space after the completed word. If the Forth dictionary has no en- tries starting with the characters before the cursor, try filename com- pletion. For complete key listings and function descriptions, see tecla(7). If the first character of the command-line is an exclamation point `!', history expansion similar to csh(1) takes place: !123 Repeats event 123. !-123 Repeats 123rd last event. !! Repeats last event (same as !-1). !str Repeats last event starting with str !?str(?) Repeats last event containing str; the last ? is op- tional. If the first character of the command-line is a caret `^', history sub- stitution similar to csh(1) takes place: ^search^replace(^) Repeats last event containing search and replace this string with replace; the last ^ is optional. Tecla Variables These variables can be set in the initialization file ~/.fthrc. *histdup* If set to gl-all, only unique history events are entered in the history list. If set to gl-prev and the last history event is the same as the current, the current command is not entered. If not defined (undef, the default), all history events are entered. *histcomment* History comment character saved in the history file, defaults to \ (backslash). *histfile* This is the pathname where history events are going to be saved and restored. If not set (undef, the default), the shell environment variable FTH_HISTORY, or, if not set, ~/.fth-history is used. *history* This is the size of the history file. If not set (undef, the default), the shell environment variable FTH_HISTORY_LENGTH or, if not set, 100 is used. *savehist* If #t, the default, saves history events in the history file. *promptstyle* If #t, enables special formatting directives within the prompt, see gl_prompt_style(3), default #f. *tecla-symbol-list* An array of strings, default empty. One can set a different list for tab-completion instead the forth dictionary. Tecla Words Bindings can be set in ~/.fthrc to control tecla(7) and gl_get_line(3). bindkey ( :optional key action -- ) This word can have no, one, or two arguments on stack. bindkey ( -- ) Shows user-defined bindings. bindkey ( key -- ) If key is a string, takes it as configure string. The string may contain more than one settings; they have to be separated by a lit- eral `\n'. The following sets edit-mode to vi and nobeep: "edit-mode vi \n nobeep" bindkey If key is a predefined constant, sets the specific value. The fol- lowing constants are valid: gl-vi Sets edit-mode to vi. gl-emacs Sets edit-mode to emacs. gl-none Sets edit-mode to none. gl-nobeep Sets nobeep mode. The following sets edit-mode to vi and nobeep with predefined con- stants: gl-vi bindkey gl-nobeep bindkey bindkey ( key action -- ) If both key and action are strings, bind action to key. "^G" "user-interrupt" bindkey If key is a string and action is anything else, unbind key from last bind. "^G" #f bindkey See tecla(7) for bindings and actions. history ( :optional action arg -- ) History events can be displayed, loaded, saved, added, and cleared where action is one of the following: gl-add arg Adds event arg to history. gl-clear Clears all history events. gl-load [arg] Loads history events from arg. If arg is nil or missing, *histfile* is used. gl-save [arg] Saves history events to arg. If arg is nil or missing, *histfile* is used. gl-show [arg] Returns a string of arg or all history events. history => returns entire history as string gl-show history => same as above 10 history => returns 10 last history events gl-show 10 history => same as above gl-load history => loads from *histfile* gl-load nil history => same as above gl-load file history => loads from FILE gl-save history => saves to *histfile* gl-save nil history => same as above gl-save file history => saves to FILE gl-add line history => adds LINE to history gl-clear history => clears entire history history-lineno ( -- n ) Returns the current line number in history. "history-next" and "history-prev" count from this number. history-next ( -- line ) Increments the current line number shown by "history-lineno" and re- turns that event. history-prev ( -- line ) Decrements the current line number shown by "history-lineno" and re- turns that event. tecla-get-line ( prompt -- line ) Prints prompt and returns input line. tecla-query-char ( prompt -- c ) Prints prompt and returns next input character. tecla-puts ( :optional text -- ) Print text formatted to maximal 78 characters per line to stdandard output. If no string was given, put a carriage return to standard output. See gl_display_text(3). tecla-read-char ( -- c ) Returns next input character. tecla-repl ( -- ) The Read-Eval-Print-Loop. Build your own interpreter. Loops Forth has loop constructs for compile state and interpret state. In addition to the usual (?)do ... (+)loop, begin ... again, begin ... until, and begin ... while ... repeat, fth provides each ... end-each and map ... end-map loops for arrays and similar objects. begin ( -- ) compile-only again ( -- ) compile-only The endless loop. Repeats body between begin and again over and over again. Press ^C to stop the endless loop. 0 begin dup . 1+ again begin ( -- ) compile-only while ( f -- ) compile-only repeat ( -- ) compile-only As long as flag f is #t, repeats body between while and repeat and starts over after begin for the next test. "test.file" io-open-read { io } begin io io-eof? not while io io-gets fth-print repeat io io-close begin ( -- ) compile-only until ( f -- ) compile-only Repeats body between begin and until as long as flag f is #f. "localhost" :port 79 io-nopen { io } io "mike\n" io-puts begin io io-gets fth-print io io-eof? until io io-close do ( limit start -- ) compile-only ?do ( limit start -- ) compile-only loop ( -- ) compile-only Runs loop from start up to but not including limit. ?do starts only if limit is greater than start. 3 0 do i . loop => 0 1 2 each ( obj -- val ) compile-only end-each ( -- ) compile-only Pushes each element of obj in order on stack and repeats execution of body. #( 0 1 2 ) each . end-each => 0 1 2 map ( obj -- ) compile-only map! ( obj -- ) compile-only end-map ( -- obj ) compile-only Sets each element of obj in order to global variable *key* and re- peats execution of body. The top of stack before end-map is set as new current value of obj. #( 0 1 2 ) value a1 a1 map i *key* + end-map => #( 0 2 4 ) \ a copy of a1 a1 .$ => #( 0 1 2 ) a1 map! i *key* + end-map => #( 0 2 4 ) \ a1 has changed a1 .$ => #( 0 2 4 ) Interpret state loops for use outside word definitions in scripts or in the repl work like their compile state cousins above. The body of the following [do] ... [loop], [each] ... [end-each] and [map] ... [end-map] is in compile state, loop indexes i, j, k and leave etc can be used like in colon definitions. [do] ( limit start -- ) [loop] ( -- ) 3 0 [do] i . [loop] => 0 1 2 [each] ( obj -- val ) [end-each] ( -- ) #( 0 1 2 ) [each] . [end-each] => 0 1 2 [map] ( obj -- ) [map!] ( obj -- ) [end-map] ( -- obj ) #( 0 1 2 ) value a1 a1 [map] i *key* + [end-map] => #( 0 2 4 ) \ a copy of a1 a1 .$ => #( 0 1 2 ) a1 [map!] i *key* + [end-map] => #( 0 2 4 ) \ a1 has changed a1 .$ => #( 0 2 4 ) REFERENCE Array Object Type A short Array Object Type example in Fth: let: #( 0 1 ) { ary } ary array-length => 2 ary 0 array-ref => 0 ary 2 array-push => #( 0 1 2 ) ary array-length => 3 ary array-shift => 0 ary array-shift => 1 ary array-shift => 2 ary array-length => 0 "" { fs } #( 0 1 2 ) to ary \ val: current value ary each { val } fs "array[%d]: %d\n" '( i val ) string-format string-push to fs end-each => "array[0]: 0\n ..." *key*: current value ary map *key* 10 * end-map => #( 0 10 20 ) ;let #() ( -- ary ) Returns an empty Array object for array-append, array-push etc. .array ( ary -- ) Prints Array object ary to current output. array->array ( ary1 -- ary2 ) Returns copy of ary1 only with references of each element in contrast to "array-copy". If ary1 is not an array, returns #( ary1 ). #( 0 #{ 'foo 10 } 2 ) value ary1 ary1 array->array value ary2 ary1 1 array-ref 'foo 30 hash-set! ary1 => #( 0 #{ 'foo 30 } 2 ) ary2 => #( 0 #{ 'foo 30 } 2 ) array->list ( ary -- lst ) Returns copy of ary as list only with references of each element in contrast to "array-copy". If ary is not an array, returns '( ary ). #( 0 #{ 'foo 10 } 2 ) value ary ary array->list value lst ary 1 array-ref 'foo 30 hash-set! lst => '( 0 #{ 'foo 30 } 2 ) ary => #( 0 #{ 'foo 30 } 2 ) array-append ( ary1 ary2 -- ary1+ary2 ) Appends two arrays and returns new one. If ary2 is not an array, ap- pends it as a single element. #( 0 1 2 ) #( 3 4 ) array-append => #( 0 1 2 3 4 ) #( 0 1 2 ) 10 array-append => #( 0 1 2 10 ) array-clear ( ary -- ) Clears array and sets all elements to #f. array-compact ( ary1 -- ary2 ) Returns new Array object with all nil elements from ary1 removed. array-compact! ( ary -- ary' ) Returns Array object with all nil elements removed. array-concat ( vals len -- ary ) alias: >array Returns Array object with len objects found on parameter stack. Raises out-of-range exception if len < 0. array-copy ( ary1 -- ary2 ) Returns copy of ary1 with all elements new created in contrast to "array->array". #( 0 #{ 'foo 10 } 2 ) value ary1 ary1 array-copy value ary2 ary1 1 array-ref 'foo 30 hash-set! ary1 => #( 0 #{ 'foo 30 } 2 ) ary2 => #( 0 #{ 'foo 10 } 2 ) array-delete! ( ary idx -- val ) Deletes and returns one element from ary at position idx. Negative index counts from backward. Raises out-of-range exception if idx is not in ary's range. array-delete-key ( ary key -- val ) Deletes and returns key from ary if found, or #f. array-fill ( ary val -- ) Sets all elements of ary to val. array-find ( ary key -- key ) Returns key if key exists in ary. array-index ( ary key -- idx ) Returns index of key in ary, or -1 if not found. array-insert ( ary idx val -- ary2 ) array-insert! Inserts val to ary at position idx and returns array. val can be any single object or an array. Negative idx counts from backward. Raises out-of-range exception if idx is not in ary1's range. array-insert! changes the original array contents. array-join ( ary sep -- str ) Returns string with all elements of ary converted to their string representation and joined together separated by sep. If sep is not a string, a space will be used as separator. #( 0 1 2 ) "--" array-join => "0--1--2" #( 0 1 2 ) nil array-join => "0 1 2" array-length ( obj -- len ) Returns length if obj is an Array object, otherwise -1. array-member? ( ary key -- f ) Returns #t if key exists in ary, otherwise #f. array-pop ( ary -- val ) Removes and returns last element of ary. If ary is empty, returns #f. array-push ( ary val -- ary' ) Appends val, which may be any object, to ary. #( 0 1 2 ) 10 array-push => #( 0 1 2 10 ) array-ref ( ary idx -- val ) Returns element at position idx. Negative index counts from back- ward. Raises out-of-range exception if idx is not in ary's range. array-reject ( ary1 proc-or-xt args -- ary2 ) array-reject! Calls proc-or-xt with the current array element as first arg and the rest from args, an array of zero or more proc arguments. The length of args + 1 is the required arity of proc-or-xt. If args is nil, an empty array is used, if args is any other object, wraps it in an ar- ray of length 1. array-reject returns a new array with elements where proc-or-xt results in #f, nil, or 0, and array-reject! removes all elements from ary where proc-or-xt results not in #f, nil, or 0. In the example n1 corresponds to the current array element and n2 comes from args, here 2. #( 0 1 2 3 4 ) lambda: <{ n1 n2 -- f }> n1 n2 > ; #( 2 ) array-reject => #( 0 1 2 ) \ or a bit shorter: #( 0 1 2 3 4 ) <'> > 2 array-reject => #( 0 1 2 ) array-reverse ( ary1 -- ary2 ) array-reverse! Returns ary1 in reversed order. array-reverse! changes the original array contents. array-search ( ary reg -- res ) Returns all elements matching regexp reg as an array. The elements are converted to their string representation before the test. array-set! ( ary idx val -- ) Stores val at position idx. Negative index counts from backward. Raises out-of-range exception if index is not in ary's range. array-shift ( ary -- val ) Removes and returns first element of ary. If ary is empty, returns #f. array-sort ( ary1 proc-or-xt -- ary2 ) array-sort! Returns sorted array. proc-or-xt compares two elements A and B and should return a negative integer if A < B, 0 if A == B, and a posi- tive integer if A > B. Raises bad-arity exception if proc-or-xt doesn't take two arguments. array-sort! changes the original array contents. #( 2 1 0 ) lambda: <{ a b -- f }> a b < if -1 else a b > if 1 else 0 then then ; array-sort => #( 0 1 2 ) array-subarray ( ary start end -- subary ) Returns array built from ary beginning with index start up to and ex- cluding index end. If end is nil, up to end of array will be re- turned. Negative index counts from backward. Raises out-of-range exception if start is not in ary's range. #( 0 1 2 3 4 ) 2 4 array-subarray => #( 2 3 ) #( 0 1 2 3 4 ) -3 -1 array-subarray => #( 2 3 4 ) #( 0 1 2 3 4 ) -3 nil array-subarray => #( 2 3 4 ) array-uniq ( ary1 -- ary2 ) array-uniq! Returns array without duplicated elements. array-uniq! changes the original array contents. array-unshift ( ary val -- ary' ) Preprends val to ary. #( 0 1 2 ) 10 array-unshift => #( 10 0 1 2 ) array= ( ary1 ary2 -- f ) Returns #t if ary1 and ary2 are Array objects of same length and con- tents, otherwise #f. array? ( obj -- f ) Returns #t if obj is an Array object. make-array ( len :key initial-element -- ary ) Returns Array object of length len filled with keyword :initial-element's values. initial-element defaults to nil if not specified. Raises out-of-range exception if len < 0. Assoc Object Type assoc? ( obj -- f ) Returns #t if obj is an Assoc object, otherwise #f. >assoc ( vals len -- ary ) Returns Assoc object with len / 2 key-value pairs found on parameter stack. Raises out-of-range exception if len < 0 or not even. assoc-array ( ass key -- key-val|#f ) alias: array-assoc If key matches, returns corresponding key-value pair from ass. assoc-ref ( ass key -- val|#f ) alias: array-assoc-ref If key matches, returns corresponding val from ass. assoc-delete! ( ass key -- ass' ) alias: array-assoc-remove! If key matches, deletes key-value pair from ass. assoc-set! ( ass key val -- ass' ) alias: array-assoc-set! assoc If key matches, sets key-value pair, otherwise adds new pair to ASS. object->assoc ( obj -- ass ) Turns obj of any kind in an Assoc object. List Object Type '() ( -- lst ) Returns empty list. .list ( lst -- ) Prints List object lst to current output. >list ( vals len -- lst ) Returns List object with len objects found on parameter stack. Raises out-of-range exception if len < 0. car ( lst -- val ) cadr ( lst -- val ) caddr ( lst -- val ) cadddr ( lst -- val ) First, second, third, or fourth element of lst or nil if list is shorter. cdr ( lst -- val ) cddr ( lst -- val ) Rest, the cdr or cddr, of lst without first or first and second ele- ment. acons ( key val alst1 -- alst2 ) Returns Lisp-like associated list from key-val pair and alst1. cons ( val lst1 -- lst2 ) cons2 ( val1 val2 lst1 -- lst2 ) Returns Lisp-like cons pointer with val as car and list as cdr or val1 as car, val2 as cadr and lst1 as cddr. cons? ( obj -- f ) Returns #t if obj is a List object, otherwise #f. last-pair ( lst -- lp ) Returns last pair of lst. '( 0 1 2 3 ) last-pair => '( 3 ) list->array ( lst -- ary ) Returns copy of lst as array only with references of each element in contrast to "list-copy". If lst is not a List object, returns #( lst ). '( 0 #{ 'foo 10 } 2 ) value lst1 lst1 list->array value ary2 lst1 1 list-ref 'foo 30 hash-set! lst1 => '( 0 #{ 'foo 30 } 2 ) ary2 => #( 0 #{ 'foo 30 } 2 ) list-append ( arg0 arg1 ... argn n -- lst ) Returns List object with n objects found on parameter stack. Raises out-of-range exception if n < 0. list-copy ( lst1 -- ary2 ) Returns copy of lst1 with all elements new created in contrast to "list->array". '( 0 #{ 'foo 10 } 2 ) value lst1 lst1 list-copy value lst2 lst1 1 list-ref 'foo 30 hash-set! lst1 => '( 0 #{ 'foo 30 } 2 ) lst2 => '( 0 #{ 'foo 10 } 2 ) list-delete ( lst1 key -- lst2 ) list-delete! Returns list without all elements equal key. list-delete! changes the original list contents. list-fill ( lst val -- lst' ) Sets all elements of lst to val. list-index ( lst key -- idx ) Returns index of key in lst, or -1 if not found. list-insert ( lst1 idx val -- lst2 ) Returns new list with val inserted to lst1 at position idx. val can be a list or any other object. Negative idx counts from backward. Raises out-of-range exception if idx is not in lst1's range. list-length ( obj -- len ) Returns length if obj is a list (nil or List object), otherwise -1. list-member? ( lst key -- f ) Returns #t if key exists in lst, otherwise #f. list-ref ( lst idx -- val ) Returns element at position idx of lst. Negative idx counts from backward. Raises out-of-range exception if idx is not in lst's range. list-reverse ( lst1 -- ary2 ) Returns new list with elements reversed. list-set! ( lst idx val -- ) Stores element val at position idx in lst. Negative idx counts from backward. Raises out-of-range exception if idx is not in lst's range. list-slice ( lst1 idx :key count 1 -- lst2 ) list-slice! Returns list without count elements from idx on. Raises out-of-range exception if idx is not in lst1's range. list-slice! changes the original list contents. #( 0 1 1 2 ) 1 :count 2 list-slice => #( 0 2 ) list-tail ( lst1 idx -- lst2 ) Returns idx'th cdr of lst1 up to the last entry in a new list, or nil. list= ( lst1 lst2 -- f ) Returns #t if lst1 and lst2 are List objects of same length and con- tents. list? ( obj -- f ) Returns #t if obj is a list (nil or List object), otherwise #f. make-list ( len :key initial-element nil -- lst ) Returns list of length len filled with keyword :initial-element's values. initial-element defaults to nil if not specified. Raises out-of-range exception if len < 0. nil? ( obj -- f ) null? ( obj --f ) Returns #t if obj is nil, otherwise #f. pair? ( obj -- f ) Returns #t if obj is a List object, otherwise #f. set-car! ( lst val -- lst' ) Sets val to car of lst. set-cdr! ( lst val -- lst' ) Sets val to cdr of lst. Alist Object Type alist? ( obj -- f ) Returns #t if obj is an Alist object, otherwise #f. >alist ( vals len -- ass ) Returns Alist object with len / 2 key-value pairs found on parameter stack. Raises out-of-range exception if len < 0 or not even. alist-list ( ass key -- key-val|#f ) alias: list-assoc If key matches, returns corresponding key-value pair from ass. alist-ref ( ass key -- val|#f ) alias: list-assoc-ref If key matches, returns corresponding value from ass. alist-delete! ( ass key -- ass' ) alias: list-assoc-remove! If key matches, removes key-value pair from ass. alist-set! ( ass key val -- ass' ) alias: list-assoc-set! If key matches, sets key-value pair, otherwise adds new pair to ass. object->alist ( obj -- ass ) Turns obj of any kind in an Alist object. General File Words Some of the following words take a mode argument which can be specified as an octal number. Put `0o', this is number zero `0' and lower letter `o', before the number similar to `0x' for hexadecimal numbers: "foo" 0o755 file-mkdir file-atime ( name -- time ) If name is a file, returns last access time. One can convert the number in a readable string with time->string. file-basename ( name ext -- base ) Returns basename of file name depending on ext. ext may be #f, nil/undef, a string or a regexp. If ext is #f, returns filename without pathname. If ext is nil or undef, discards the part from the last dot to the end of basename name. If ext is a string or a reg- exp, discards found ext from basename name. "/home/mike/cage.snd" #f file-basename => "cage.snd" "/home/mike/cage.snd" nil file-basename => "cage" "/home/mike/cage.snd" "nd" file-basename => "cage.s" "/home/mike/cage.snd" /\.(snd|wave)$/ file-basename => "cage" file-chdir ( path -- ) alias: chdir Changes working directory to path and, if in a repl, prints new path to current standard output. If path is nil, changes working direc- tory to HOME. path may contain `~' as an abbreviation for home di- rectory, see chdir(2). file-chmod ( name mode -- ) Changes access mode of file name to mode, see chmod(2). file-chroot ( path -- ) Changes root directory to path and, if in a repl, prints new path to current standard output. See chroot(2) for more information. file-copy ( src dst -- ) Copies file src to dst. If dst is a directory, copy src to dst/src. Raises system-error exception if fopen(3) fails on any of the two files. file-ctime ( name -- time ) If name is a file, returns status change time. One can convert the number in a readable string with time->string. file-delete ( name -- ) If file name exists, delete it, otherwise do nothing, see unlink(2). file-dir ( dir -- files-ary ) Returns an array with all files found in dir. file-dirname ( name -- path ) Returns directory part of name. "/home/mike/cage.snd" file-dirname => "/home/mike" file-eval ( name -- ) Loads and evals contents of file name and adds name to *loaded-files* if it wasn't already there. It's similar to include except that name must be on stack (while include is a parse word). With file-eval one can load files from within word definitions. Raises load-error ex- ception if file-eval fails. file-fullpath ( name -- path ) Returns string with current working directory added in front of name. If name starts with a slash, returns name unchanged. file-install ( src dst mode -- f ) Installs src to dst with access mode if dst doesn't exist or if modi- fication time of src is greater than dst's. If dst is a directory, installs src to dst/src. Returns #t, if src could be installed, oth- erwise #f. : install-lib { src dst mode -- } src dst mode file-install if "%s --> %04o %s" '( src mode dst ) else "%s is up-to-date" '( dst ) then fth-print cr ; "libsndlib.so" "/usr/opt/lib/s7" 0o755 install-lib file-length ( name -- len ) If name is a file, returns length in bytes. file-match-dir ( dir reg -- files-ary ) Returns an array of filenames in dir matching regexp reg. file-mkdir ( name mode -- ) Creates directory name with access mode, see mkdir(2). file-mkfifo ( name mode -- ) Creates fifo file name with access mode, see mkfifo(2). file-mtime ( name -- time ) If name is a file, returns last modification time. One can convert the number in a readable string with time->string. file-pwd ( -- path ) Returns current working directory, see getcwd(3). file-realpath ( name -- path ) If name starts with `~', replace it with contents of environment variable HOME. If realpath(3) is successful, the resolved path will be returned, otherwise name with `~' replacement will be returned. "~" file-realpath => "/home/mike" "/usr/pkg" file-chdir => "/usr/pkg" file-pwd => "/usr/pkg" "../bin" file-realpath => "/usr/bin" file-rename ( src dst -- ) Renames src to dst, see rename(2). file-rmdir ( name -- ) Removes empty directory name, see rmdir(2). file-shell ( cmd -- str ) alias: shell Opens a pipe for reading, feeds it with the shell command line cmd and returns the output as string. cmd may be a string or an array of strings, see "io-popen". After execution, the exit-status variable is set. file-split ( name -- ary ) Splits name in dirname and basename and returns the result in an ar- ray of two strings. "/home/mike/cage.snd" file-split => #( "/home/mike" "cage.snd" ) file-symlink ( src dst -- ) Creates symlink from src to dst, see symlink(2). file-system ( cmd -- f ) Executes shell command cmd. Sets the read-only variable exit-status and returns #t for success or #f if something went wrong. In the latter case you may check exit-status. file-touch ( name time -- ) Changes modification time of name to time. If time is nil, changes to current time. \ set modification time an hour earlier "main.c" current-time 3600 - file-touch \ reset modification time to current time "main.c" nil file-touch file-truncate ( name size -- ) Changes name's length to size bytes, see truncate(2). Forth Pipe Words In addition to the Standard Forth Words open-file and close-file, here are the corresponding pipe words. open-pipe ( addr u fam -- fp ior ) Opens a pipe with name and mode addr u fam and returns the file pointer fp and return code ior. close-pipe ( fp -- ior ) Closes the file pointer fp and returns code ior. This example reads from the shell command pwd(1) and prints the result to standard output: 256 constant max-line create line-buffer max-line 2 + allot s" pwd" r/o open-pipe throw value FP line-buffer max-line FP read-line throw drop line-buffer swap type FP close-pipe throw File Test Words file-block? ( name -- f ) Returns #t if name is a block special file, see test(1) option -b. file-character? ( name -- f ) Returns #t if name is a character special file, see test(1) option -c. file-directory? ( name -- f ) Returns #t if name is a directory, see test(1) option -d. file-executable? ( name -- f ) Returns #t if name is an executable file, see test(1) option -x. file-exists? ( name -- f ) Returns #t if name is an existing file, see test(1) option -e. file-fifo? ( name -- f ) Returns #t if name is a named pipe, see test(1) option -p. file-grpowned? ( name -- f ) Returns #t if name matches effective group id, see test(1) option -G. file-owned? ( name -- f ) Returns #t if name matches effective user id, see test(1) option -O. file-readable? ( name -- f ) Returns #t if name is a readable file, see test(1) option -r. file-setgid? ( name -- f ) Returns #t if name has group id flag set, see test(1) option -g. file-setuid? ( name -- f ) Returns #t if name has user id flag set, see test(1) option -u. file-socket? ( name -- f ) Returns #t if name is a socket, see test(1) option -S. file-sticky? ( name -- f ) Returns #t if name has sticky bit set, see test(1) option -k. file-symlink? ( name -- f ) Returns #t if name is a symbolic link, see test(1) option -h. file-writable? ( name -- f ) Returns #t if name is a writable file, see test(1) option -w. file-zero? ( name -- f ) Returns #t if length of file name is zero. Hash Object Type A short Hash Object Type example in Fth: let: #{} { hs } hs 'a #( 0 1 2 ) hash-set! hs .hash => #{ 'a => #( 0 1 2 ) } hs 'b "text" hash-set! hs .hash => #{ 'a => #( 0 1 2 ) 'b => "text" } hs 'a hash-ref => #( 0 1 2 ) hs 'b hash-ref => "text" hs 'c hash-ref => #f hs 'a hash-delete! => '( 'a #( 0 1 2 ) ) hs .hash => #{ 'b => "text" } hs hash-clear hs .hash => #{} "" { fs } #{ 'a 6 } to hs \ val: current '( key val ) hs each { val } fs "%s: %s\n" val string-format string-push to fs end-each => "'a: 6\n" \ *key*: current '( key val ) hs map *key* 1 array-ref 10 * end-map => #{ 'a 60 } ;let Words follow handling Hash Object Types: .hash ( hash -- ) Prints hash object to current output. >hash ( vals len -- hash ) Takes len / 2 key-value pairs from parameter stack and returns Hash object. Raises out-of-range exception if len < 0 or len is not even. 'a 0 'b 1 4 >hash => #{ 'a => 0 'b => 1 } hash->array ( hash -- ass ) Returns array with #( key value ) pairs of hash's contents. #{ 'a 0 'b 1 } hash->array => #( #( 'a 0 ) #( 'b 1 ) ) hash-clear ( hash -- ) Removes all entries from hash, hash's length becomes zero. hash-copy ( hash1 -- hash2 ) Returns copy of hash1 using object-copy for all elements. hash-delete! ( hash key -- ary ) Deletes key-value pair associated with key and returns key-value ar- ray, or #f if not found. hash-each ( hash proc-or-xt -- ) Runs proc-or-xt for each key-value pair. proc-or-xt's stack effect must be ( key val -- ). #{ 'a 0 'b 1 } lambda: <{ key val -- }> "%s=%s\n" #( key val ) fth-print ; hash-each hash-equal? ( obj1 obj2 -- f ) alias: hash= Returns #t if obj1 and obj2 are Hash objects with same length and contents. hash-find ( hash key -- ary ) Returns key-value array if key exists, or #f if not found. hash-keys ( hash -- keys ) hash-values ( hash -- vals ) Returns array of keys resp. values. hash-length ( obj -- len ) Returns length if obj is a Hash object, otherwise -1. hash-map ( hash1 proc-or-xt -- hash2 ) Runs proc-or-xt for each key-value pair. proc-or-xt's stack effect must be ( key value -- val ) where val is the new value for key. #{ 'a 0 'b 1 } lambda: <{ key val -- val }> val 10 + ; hash-map => #{ 'a => 10 'b => 11 } hash-member? ( hash key -- f ) Returns #t if key exists, otherwise #f. hash-ref ( hash key -- value ) Returns associated value, or #f if key was not found. hash-search ( hs reg -- res ) Returns all values of matching keys in an array. The keys are con- verted to their string representation before the test. hash-set! ( hash key value -- ) Sets key-value pair of hash. If key exists, overwrites existing value, otherwise creates new key-value entry. hash? ( obj -- f ) Returns #t if obj is a Hash object, otherwise #f. make-hash ( -- hash ) alias: #{} Returns fresh empty Hash object. make-hash-with-len ( size -- hash ) Returns fresh new Hash object with size key-value pairs. Keys are 0, 1, 2, ... and values are nil. Properties There exists a global hash "properties" variable, which can be used for every kind of information. Furthermore, every object created with "fth_make_instance, see" libfth(3), as well as every ficlWord has a property-slot, for those see "object-properties" as well as "word-properties". Usage of properties: #f properties => #{} "string" value obj obj 'a "hello" property-set! obj 'a property-ref => "hello" obj 'b property-ref => #f obj properties => #{ 'a => "hello" } #f properties => #{ "string" => #{ 'a => "hello" } } properties ( obj -- props ) Returns obj's property from the global properties hash, or #f if empty. If obj is #f, returns entire global properties hash. property-ref ( obj key -- val ) Returns obj's value associated with key from the global properties hash variable, or #f. property-set! ( obj key val -- ) Sets key-value pair for obj at the global properties hash variable. If key already exists, overwrites old value. Usage of object-properties: "string" value obj obj 'a "hello" object-property-set! obj 'a object-property-ref => "hello" obj 'b object-property-ref => #f obj object-properties => #{ 'a => "hello" } object-properties ( obj -- props ) Returns obj's properties, or #f if empty. object-property-ref ( obj key -- val ) Returns obj's property val associated with key, or #f if not found. object-property-set! ( obj key val -- ) Sets key-value pair to obj's property object. If key already exists, overwrites old value. Usage of word-properties: <'> noop 'a "hello" word-property-set! <'> noop 'a word-property-ref => "hello" <'> noop 'b word-property-ref => #f <'> noop word-properties => #{ 'a => "hello" \ 'documentation => "noop" } word-properties ( xt -- props ) Returns xt's properties, or #f. word-property-ref ( xt key -- val ) Returns xt's property val associated with key, or #f. word-property-set! ( xt key val -- ) Sets key-value pair to xt's property object. If key already exists, overwrites old value. Hook Object Type .hook ( hook -- ) Prints Hook object hook to current output. create-hook ( arity help "name" -- ) Creates hook variable name with arity and documentation help. arity can be an integer or an array of length 3, #( req opt rest ). 2 "A simple hook." create-hook my-new-hook #( 2 0 #f ) "A simple hook." create-hook my-new-hook hook->array ( hook -- procs ) aliases: hook->list hook-procs Returns array of all of hook's procedures. hook-add ( hook proc-or-xt -- ) alias: add-hook! Adds hook procedure proc-or-xt to hook. Raises bad-arity exception if proc-or-xt's arity doesn't match hook's arity. hook-apply ( hook args -- value-list ) alias: run-hook Runs each of hook's procedures with args, a single argument or an ar- ray of arguments, and returns an array of results of all hook-proce- dures. Raises bad-arity exception if args's length doesn't match hook's arity. 2 make-hook value hk1 hk1 <'> + 2 make-proc add-hook! hk1 #( 1 2 ) run-hook => #( 3 ) hook-arity ( hook -- arity ) Returns hook's arity as an array of reqired, optional, and rest argu- ments #( req opt rest ). 2 make-hook hook-arity => #( 2 0 #f ) hook-clear ( hook -- ) alias: reset-hook! Removes all of hook's procedures. hook-delete ( hook proc-or-name -- prc ) alias: remove-hook! Removes hook procedure proc-or-name from hook and returns it. proc-or-name can be a string, an xt or a Proc object. hook-empty? ( hook -- f ) Returns #t if hook has no hook procedures, otherwise #f. hook-member? ( hook proc-or-name -- f ) Returns #t if hook has procedure proc-or-name, otherwise #f. proc-or-name can be a string, an xt or a Proc object. hook-name ( hook -- name ) Returns hook's name as string, or #f. hook-names ( hook -- name-list ) Returns array of all of hook's procedure names (strings). hook= ( obj1 obj2 -- f ) Returns #t if obj1 and obj2 are Hook objects with same arity and pro- cedures, otherwise #f. hook? ( obj -- f ) Returns #t if obj is a Hook object, otherwise #f. make-hook ( arity -- hook ) Returns Hook object for procedures accepting arity arguments. arity can be an integer or an array of length 3, #( req opt rest ). 2 make-hook value my-new-hook #( 2 0 #f ) make-hook value my-new-hook IO Words There are several IO words for manipulating file and pipe streams, strings and sockets. Words like "io-read" and "io-write" handle file, pipe, string, and socket IO objects. Global Variables *stdin* *stdout* *stderr* Current input, output, and error IO object. set-*stdin* ( io -- old ) set-*stdout* ( io -- old ) set-*stderr* ( io -- old ) They set io as the current input, output, and error IO object and re- turn the old one. version-control ( -- val ) set-version-control ( val -- ) Returns or sets current version control style. Accepted values for setting: #t Numbered backups. nil Numbered/simple backups. #f Simple backups. undef No backups. Open IO io-open-file ( :key fam r/o args -- io ) io-open-input-file ( :key args -- io ) io-open-output-file ( :key args -- io ) These words open files, pipes, strings, sockets and soft ports. For the full set of keyword arguments, see "make-soft-port". Examples :filename "foo" io-open-file value io1 :command "ls -lF" io-open-file value io2 :string "test string" io-open-file value io3 :socket nil :port 79 io-open-file value io4 :soft-port "test" io-open-file value io5 Open File Object io-open ( name :key fam r/o if-exists overwrite -- io ) io-open-read ( name -- io ) io-open-write ( name :key if-exists overwrite -- io ) make-file-port make-file-input-port make-file-output-port They open file name and return the new IO object ready for process- ing. The make- words are aliases for the corresponding io- ones. The following constants are predefined for file access mode :fam: a/o Append (a). w/a Read/write-append (a+). r/o Read-only (r). r/a Read/write (r+), for open read/write pipes with io- popen. w/o Write-only (w). r/w Read/write/create (w+). If the keyword :if-exists was not specified, overwrites a possible ex- isting file if opened for writing. The following :if-exists keywords are provided: :error Raises io-error exception if name already exists. :overwrite Overwrites existing file (default). :rename Depends on the environment variable VERSION_CONTROL and the global Fth variable "version-control". Examples "in-test" io-open value ro1 "in-test" :fam r/o io-open value ro2 "out-test" :fam w/o io-open value wo1 "out-test" :fam w/o :if-exists :overwrite io-open value wo2 "out-test" :fam r/w :if-exists :error io-open value rw1 "out-test" :fam r/w :if-exists :rename io-open value rw2 Open Pipe Object io-popen ( cmd :key fam r/o -- io ) io-popen-read ( cmd -- io ) io-popen-write ( cmd -- io ) make-pipe-port make-pipe-input-port make-pipe-output-port They open a pipe command cmd and return the new IO object ready for processing. cmd may be a string or an array of strings. If popen(3) allows mode "r+" (read/write mode), io-popen can be opened read/write with :fam r/a. The make- words are aliases for the corresponding io- ones. If the global environment variable FTH_POPEN_SHELL is defined and has a shell pathname, popen(3) uses this shell for execution. Examples \ read pipe "ls -lAF ~/" io-popen-read value rio \ or #( "ls" "-lAF" "~/" ) io-popen value rio rio io->string fth-print rio io-close \ write pipe "cat" io-popen-write value wio wio "hello" io-puts wio io-close \ read/write pipe (only where mode "r+" is allowed) "fth -" :fam r/a io-popen value rwio rwio "80 f2c\n" io-puts rwio io-gets fth-print rwio io-close Open String Object io-sopen ( str :key fam r/o -- io ) io-sopen-read ( str -- io ) io-sopen-write ( str -- io ) make-string-port make-string-input-port make-string-output-port They open a string str and return the new IO object ready for pro- cessing. The make- words are aliases for the corresponding io- ones. Examples "test-string" value s s io-sopen value rio rio io-read fth-print rio io-close s :fam w/a io-sopen value aio aio " with appended contents" io-write aio io-rewind aio io-read fth-print aio io-close s fth-print => "test-string with appended contents" Open Socket Object io-nopen (host :key args -- io ) make-socket-port These special keywords with default values are known: :port 1024 :domain AF_INET6 (or AF_INET, AF_UNIX) :type SOCK_STREAM (or SOCK_DGRAM) :fam r/w (or server) Opens a new socket server or connects to an already established one. host is a host name (AF_INET/AF_INET6) or a path name (AF_UNIX). If host is not a string, "localhost" will be used. port is the connec- tion port (default 1024) if domain is AF_INET/AF_INET6, otherwise un- used, and domain can be AF_INET6 (default), AF_INET, or AF_UNIX. If the :domain keyword was specified, uses that domain, otherwise socket(2) tries AF_INET6 first. If that fails, tries AF_INET. type can be SOCK_STREAM or SOCK_DGRAM. socket(2) is opened with domain, type, and hard-coded flag 0. fam can be r/w (default) or server. In the latter case, the returned IO object is opened as a server, other- wise the IO object is opened as a client. Raises socket-error excep- tion if socket(2) or connect(2) fail. The make- word is an alias. Examples "localhost" :port 25 io-nopen value io io "HELP\r\n" io-puts io io-gets fth-print io io-close General IO Words .io ( io -- ) Prints io object to current output. io->string ( io -- str ) Returns contents of io object as string if possible. io-address ( io -- ip-addr ) If io is a socket, returns the IP address of the IO object (as string). io-close ( io -- ) Flushes and closes io object and sets closed? to #t. io-closed? ( io -- f ) Returns #t if io object is closed, otherwise #f. io-eof? ( io -- f ) alias: io-eos? Returns #t if EOF is reached, otherwise #f. io-exit-status ( -- n ) alias: exit-status Returns exit status of last extern process from "file-shell", "file-system", etc. io-fdopen ( fd :key fam r/o -- io ) Connects the file descriptor fd to a new IO object. If keyword fam was not specified, opens file read-only, otherwise uses fam. See "io-open" for fam. 2 :fam w/o io-fdopen value err-io err-io "our error log" io-write err-io io-flush => "our error log" (on standard error) io-filename ( io -- name ) alias: io-hostname Returns filename of io object or #f if filename is not available. If io is a socket, it will return the hostname instead. io-fileno ( io -- fd ) alias: io-fd Returns file descriptor of io. io-flush ( io -- ) Flushes io object. io-getc ( io -- c ) Returns next character from io object or #f if EOF. io-input? ( obj -- f ) io-output? ( obj -- f ) Returns #t if obj is an in- or output IO object, otherwise #f. io-mode ( io -- mode ) Returns access mode of io object as string. io-pos-ref ( io -- pos ) alias: io-tell Returns current io object position. io-pos-set! ( io pos -- ) Sets io object position to pos. io-putc ( io c -- ) Writes character c to io object. io-read ( io -- line ) aliases: io-gets io-recv Returns next line from io object or #f if EOF. io-readlines ( io -- array-of-lines ) Returns the entire io object contents as an array of strings, line by line. io-reopen ( io1 name :key fam io1-fam -- io2 ) Returns a new IO object as copy of io1 and closes io1. If name is not a string, uses filename from io1. If keyword fam was not speci- fied, uses mode from io1, otherwise uses fam. All restrictions on freopen(3) apply, for example a file opened for reading cannot re- opened for writing etc. "1-test" io-open-write value io1 io1 "hello" io-write io1 "2-test" io-reopen value io2 io1 io-closed? => #t io2 "world" io-write io2 io-close io2 io-closed? => #t "1-test" readlines => #( "hello" ) "2-test" readlines => #( "world" ) *stderr* "error.log" io-reopen value err-io io-rewind ( io -- ) Rewinds position to begin of io object. io-seek ( io offset :key whence io-seek-set -- pos ) Adds offset to the file position of io object and returns the new po- sition. Keyword whence can have the following values: SEEK_SET Offset counts from begin of file (default). SEEK_CUR Offset counts from current position. SEEK_END Offset counts from end of file. io-select ( :key readfds writefds exceptfds timeout -- f ) There are three keyword arguments for specifying the IO object and one keyword argument for the timeout option: :readfds io :writefds io :exceptfds io :timeout microseconds One can check all three IO objects, but not more than one of a kind. It's best to check only one because so you know for which the return flag was set. See select(2). io-tmpfile ( -- io ) Creates a temporary file IO object that is automatically removed when it is closed or on program termination. See tmpfile(3) and mkstemp(3). io-write ( io line -- ) aliases: io-puts io-send Writes line to io object. io-write-format ( io fmt args -- ) Writes formatted string to io object. io-writelines ( io array-of-lines -- ) Writes array-of-lines to io object. io= ( obj1 obj2 -- f ) Returns #t if obj1 and obj2 are IO objects with equal filenames, modes and file positions. io? ( obj -- f ) Returns #t if obj is an IO object, otherwise #f. readlines ( name -- array-of-lines ) Opens file name, reads its contents in an array, closes file and re- turns the array. writelines ( name array-of-lines -- ) Opens file name, writes the contents of array-of-lines to it and closes file. fd-close ( obj -- ) If obj is an IO object, "io-close" is used, if obj is a file descrip- tor, an integer between 0 and OPEN_MAX (128), close(2) is used. fd-dup2 ( old-fd new-fd -- ) Guarantees that the file table entry of new-fd shares that of old-fd. See dup2(2). fd-ioctl ( fd request flag -- res ) Manipulates open file descriptors. fd is a file descriptor, flag is 0 or 1 and request is one of the following constants: FIOCLEX Sets the close-on-exec flag. FIONCLEX Clears the close-on-exec flag. FIONBIO Set or clear the nonblocking I/O flag. FIOASYNC Set or clear the flag that allows the receipt of asyncro- nous I/O signals, SIGIO. FIONREAD Returns the number of bytes available to read. This works for files, pipes, and sockets. FIOSETOWN Set either the process ID or the process group ID to re- ceive the SIGIO and SIGURG signals (sockets). FIOGETOWN Get either the process ID or the process group ID that is set to receive SIGIO and SIGURG signals. See ioctl(2). fd-read ( fd -- line ) If the file descriptor fd, an integer between 0 and OPEN_MAX (128), returns 0, #f for EOF is returned, otherwise the read line is re- turned. See also read(2). fd-write ( fd line -- ) The line is written to the opened file descriptor fd, an integer be- tween 0 and OPEN_MAX OPEN_MAX (128). See also write(2). Socket Words The meaning of and possible values for arguments for the following words: fd is the file descriptor returned by socket(2), port is the port number to use, domain is one of AF_UNIX, AF_INET or AF_INET6, type is one of SOCK_STREAM or SOCK_DGRAM, host is either the path name for domain AF_UNIX or the host name for AF_INET/AF_INET6, and flags is one of 0, MSG_PEEK or MSG_OOB. If something went wrong, they raise socket-error exception. net-eos? ( fd -- ) Tests for end of stream for socket descriptor fd. make-sockaddr ( host port domain -- addr ) Creates a sockaddr struct for "net-sendto" and "net-recvfrom". make-socket-io ( fd -- io ) alias: net-fd->io Creates a socket IO object from fd. net-accept ( fd host domain -- io ) Accepts a connection on a socket and returns an IO object after an connection is established. fd is a socket descriptor, host can be an arbitrary name, its only use is the name for the IO object, domain can be AF_INET, AF_INET6, or AF_UNIX. This is used on the server side of a socket connection, see accept(2). net-bind ( fd host port domain -- ) Assigns a name to a socket. fd is the socket descriptor, host is a host name (AF_INET/AF_INET6) or a path name (AF_UNIX), port is the port if domain is AF_INET/AF_INET6, otherwise unused, and domain can be AF_INET, AF_INET6, or AF_UNIX. This is on the server side of a socket connection, see bind(2). net-connect ( fd host port domain -- io ) Connects to a server and returns IO object after a connection is es- tablished. fd is a socket descriptor, host is a host name (AF_INET/AF_INET6), or a path name (AF_UNIX), port is the port if domain is AF_INET/AF_INET6, otherwise unused, and domain can be AF_INET, AF_INET6, or AF_UNIX. This is on the client side of a socket connection, see connect(2). net-listen ( fd -- ) Informs the operating system that connection requests should be de- livered. fd is an open socket descriptor. This is on the server side of a socket connection, see listen(2). net-recv ( fd flags -- msg ) net-recvfrom ( fd flags addr -- msg ) net-recvfrom2 ( fd flags host port domain -- msg ) net-send ( fd msg flags -- ) net-sendto ( fd msg flags addr -- ) net-sendto2 ( fd msg flags host port domain -- ) They send and receive data through the socket descriptor fd, see ex- amples below and recv(2) and recvfrom(2) as well as send(2) and sendto(2). net-shutdown ( fd how -- ) Closes a socket connection. fd is a socket descriptor and how is one of SHUT_RD, SHUT_WR, or SHUT_RDWR, see shutdown(2). net-socket ( domain type -- fd ) Returns a socket descriptor. domain can be AF_INET6, AF_INET, or AF_UNIX, type can be SOCK_STREAM or SOCK_DGRAM, see socket(2). net-socketpair ( type -- fd-ary ) Returns an array of a socket descriptor pair. The domain can be only AF_UNIX (AF_LOCAL), so it's hardwired. type can be SOCK_STREAM or SOCK_DGRAM, see socketpair(2). net-getpeername ( fd -- name ) Returns socket name, the foreign name, of fd. See getpeername(2). net-getsockname ( fd -- name ) Returns socket name, the local name, of fd. See getsockname(2). gethostbyaddr ( ip -- hash ) .gethostbyaddr ( ip -- ) Returns resp. prints a hash with slots 'name (string), 'aliases (ar- ray), and 'addr-list (array) filled with results from gethostbyaddr(3) looking for ip (a string). .gethostbyaddr prints these entries nicely. gethostbyname ( host -- hash ) .gethostbyname ( host -- ) Returns resp. prints a hash with slots 'name (string), 'aliases (ar- ray), and 'addr-list (array) filled with results from gethostbyname2(3) looking for host (a string). .gethostbyname prints these entries nicely. getservbyname ( serv -- hash ) .getservbyname ( serv -- ) Returns resp. prints a hash with slots 'name (string), 'aliases (ar- ray), 'port (integer), and 'protocol (string) filled with results from getservbyname(3) looking for service serv (a string). .getservbyname prints these entries nicely. getservbyport ( port -- hash ) .getservbyport ( port -- ) Returns resp. prints a hash with slots 'name (string), 'aliases (ar- ray), 'port (integer), and 'protocol (string) filled with results from getservbyport(3) looking for port (a number). .getservbyport prints these entries nicely. h_errno ( -- n ) Returns the h_error number, the error set by network host functions like gethostbyname(3). hstrerrno ( n -- str ) Returns the error message string corresponding to h_error n. h_error is the current error number set by network host functions like gethostbyname(3). Socket Examples This is the simple TCP client/server network example found in Chapter 6 of UNIX Network Programming (1990) by W. Richard Stevens. \ \ The server reads one line at a time from the socket \ and writes each line back to the sender. \ : str-echo { so -- } nil { line } begin so io-gets to line line "\n" string<> while so line io-puts repeat ; \ \ The client reads one line from file IO and writes it to the socket, \ then reads a line back from the socket and writes it to *stdout*. \ : str-cli { so io -- } nil { line } begin io io-gets to line line ".\n" string<> while so line io-puts *stdout* so io-gets io-puts repeat so "\n" io-puts ; \ \ Callback for server. \ : echo-cb { so sfd -- prc; self -- } 0 proc-create ( prc ) sfd , so , does> { self -- } self @ ( sfd ) fd-close self cell+ @ { so } so str-echo %s finished\n" '( so ) fth-stderr so io-close ; \ \ Start the TCP server at one terminal. \ : tcp-server ( -- ) "0.0.0.0" { serv-addr } "localhost" { cli-addr } 6543 { port } AF_INET SOCK_STREAM net-socket { sfd } sfd serv-addr port AF_INET net-bind sfd net-listen begin sfd cli-addr AF_INET net-accept ( so ) sfd echo-cb fork ." pid " . cr again ; \ \ Start the TCP client at a second terminal and begin writing. \ The server echos each line back. \ : tcp-client ( -- ) "localhost" { serv-addr } 6543 { port } AF_INET SOCK_STREAM net-socket { sfd } serv-addr port AF_INET net-connect ( so ) *stdin* str-cli ; Miscellaneous Constants FICL_VM_STATE_INTERPRET INTERPRET_STATE FICL_VM_STATE_COMPILE COMPILE_STATE Compile or interpret state constants for comparison with global variable state. state @ COMPILE_STATE = if \ compile state action here else \ interpret state action here then Bytes cell dfloat float sfloat Number of bytes used by a cell or float. String Constants ficl-version fth-date fth-version Version and date strings of current program and library. Loading Source Files *features* Array of all features. add-feature ( feature -- ) Adds feature, a string or symbol, to *features* list. 'snd add-feature add-load-lib-path ( path -- ) Adds string path to *load-lib-path* array if not already there. "/home/mike/lib/fth" add-load-lib-path add-load-path ( path -- ) Adds string path to *load-path* array if not already there. "/home/mike/share/fth" add-load-path apropos ( obj -- ary ) Returns array of dictionary entries matching regular expression or string obj. /do/ apropos => #( "doLocal" ... ) dl-load ( "lib" "func" -- ) Loads dynamic C library lib and calls init function func. dl-load dbm Init_dbm include ( "name" -- ) Loads Forth source file name and adds name to *loaded-files* if it wasn't already there. If file extension wasn't specified, use `.fs'. If name doesn't exist, tries each entry of *load-path* with name. Replaces `~' with HOME if name begins with this character. With include one can load a file more than once. Before loading name, runs hook "before-load-hook". After loading name, runs hook "after-load-hook". Raises no-such-file exception if file doesn't ex- ist and load-error exception if an error occurred during load. include hello install ( "file" -- ) Installs file in first writeable path found in *load-path* (*.fs[m]) or *load-lib-path* (*.so). In the last example below the trailing -e is necessary because the last occurrence of -e will be compiled but install is a parse word and won't work in compile state. \ from script: install snd-test.fs install sndlib.so \ from shell command prompt: % fth -ve 'install sndlib.so' -e '' install-file ( file -- ) Installs file in first writeable path found in *load-path* (*.fs[m]) or *load-lib-path* (*.so). Warns if no writable path could be found. \ from script: "snd-test.fs" install-file "sndlib.so" install-file \ from shell command prompt: % fth -ve '"sndlib.so" install-file' load-init-file ( file -- ) If Forth source file exists in current or HOME directory, loads it, otherwise does nothing. Replaces `~' with HOME if name begins with this character. ".my-fth-init" load-init-file provided? ( obj -- f ) Returns #t if obj, a string or symbol, exists in *features* list. 'fth provided? => #t 'foo provided? => #f require ( "name" -- ) If Forth source file name doesn't exist in array *loaded-files*, load it and add name to *loaded-files*. If file extension wasn't speci- fied, use `.fs'. If name doesn't exist, tries each entry of *load-path* with name. Replaces `~' with HOME if name begins with this character. With require one can load files only once. Before loading name, runs hook "before-load-hook". After loading name, runs hook "after-load-hook". Raises no-such-file exception if file doesn't exist and load-error exception if an error occurred during load. require hello unshift-load-lib-path ( path -- ) Adds string path at the front of the *load-lib-path* array if not al- ready there. "/home/mike/lib/fth" unshift-load-lib-path unshift-load-path ( path -- ) Adds string path at the front of the *load-path* array if not already there. "/home/mike/share/fth" unshift-load-path Catch Errors fth-catch ( ?? obj exc arg -- ?? res ) If obj is #f, returns immediately #f, if obj is a proc-or-xt, exe- cutes obj. If obj finishes successfully, returns #f on top of stack and obj's results if any as ( obj-results #f ). If something went wrong, catching depends on exc and returning on arg. If exc is #t, all exceptions will be caught, if exc is an ex- ception, only this exception will be caught. The return value depends an arg. If arg is nil, '( exc exc-msg ) will be returned, if arg is a proc-or-xt, the result of this will be returned, if arg is neither nil nor a proc-or-xt, arg itself will be returned. obj Can be #f or a proc-or-xt. If #f, finishes immediately and returns #f. If obj is a proc-or-xt, obj will be executed and, if successfully finished, its return value as well as #f on top of stack will be returned ( res #f ). exc Can be #t or an exception. If #t, all exceptions will be caught. If exc is an exception, this exception only will be caught. arg If something went wrong, this lands on top of stack. It can be nil, a proc-or-xt returning a value or any other ob- ject. If nil, the caught exception will be on top of stack. If arg is a proc-or-xt, this will be executed and its return value will be on top of stack. The stack effect of arg's proc-or-xt is ( oldval -- newval ) where oldval is a list '( exc exc-msg ). If arg is any other value, arg itself will be returned. #( 0.3 0.3 0.3 ) value ary ary 2 <'> array-ref #t nil fth-catch => 0.3 #f ary 4 <'> array-ref 'out-of-range #t fth-catch => #( 0.3 0.3 0.3 ) 4 #t : ary-handler { retval -- val } "from handler: %S\n" #( retval ) fth-print #t ( return value ) ; ary 4 0.4 <'> array-set! 'out-of-range <'> ary-handler fth-catch prints: => from handler: \ #( 'out-of-range "array-set! (ary_set) arg 2: \ 4 is out of range" ) => 0.4 #t ary 2 0.4 <'> array-set! 'out-of-range <'> ary-handler fth-catch => #f fth-raise ( exc fmt args -- ) Raises exception exc with text built from fmt and args. If fmt is a format string with N printf-like-format signs, args should have at least N elements with corresponding formatting values. If exc is #f, reraise last exception. 'bad-arity "%s: %s args required, got %s" #( proc 3 2 ) fth-throw => #<bad-arity in test-proc: 3 args required, got 2> #f #f #f fth-raise => reraise last exception fth-throw ( exc args -- ) Throws exception exc with text built from args. If args is not an array, its string representation is used. If args is NIL or an empty array, a default string is used. If args is an array with one ele- ment, this string is used. If args is an array and its first element is a format string with N printf-like-format signs, args should have N more elements with corresponding formatting values. \ \ ARGS: any object \ 'bad-arity proc fth-throw => #<bad-arity in test-proc> \ \ ARGS: nil or #() \ 'bad-arity nil fth-throw => #<bad-arity: proc has bad arity> \ \ ARGS: #( string ) \ 'bad-arity #( "test-proc" ) fth-throw => #<bad-arity in test-proc> \ \ ARGS: #( fmt arg1 arg2 arg3 ) \ 'bad-arity #( "%s: %s args required, got %s" proc 3 2 ) fth-throw => #<bad-arity in test-proc: 3 args required, got 2> stack-reset ( ?? -- ) Resets (empties) the data stack to initial state. Time Words current-time ( -- secs ) Returns time in seconds since 1970/01/01 as ficl2Unsigned. See time(3) for more information. date ( -- str ) Returns date in default Unix format as a string. gmtime ( secs -- ary ) Returns array of eleven elements with secs converted to Coordinated Universal Time UTC. See gmtime(3) for more information. sec Seconds after minute (0-60). min Minutes after the hour (0-59). hour Hours since midnight (0-23). mday Day of the month (1-31). mon Months since January (0-11). year Years since 1900. wday Days since Sunday (0-6). yday Days since January 1 (0-365). isdst Daylight savings time flag. tm_gmtoff Offset from UTC in seconds. tm_zone Time-zone abbreviation. localtime ( secs -- ary ) Returns array of eleven elements with secs converted to local time, see "gmtime" for array elements and localtime(3) for more informa- tion. mktime ( ary -- secs ) Returns time constructed from values of ary. ary may be #f or an ar- ray of up to eleven elements where single elements may be #f, see "gmtime" for array elements and mktime(3) for more information. #( 28 40 2 14 0 112 6 13 #f 3600 "CET" ) mktime strftime ( fmt secs -- str ) Converts ficl2Unsigned secs in a date string corresponding to fmt. The fmt string will be interpreted by strftime(3). "%a %b %d %H:%M:%S %Z %Y" current-time strftime => "Sat Jan 14 02:40:28 CET 2012" strptime ( str fmt -- secs ) Parses str according to fmt with strptime(3) and returns seconds as ficl2Unsigned. "2012 01 14" "%Y %m %d" strptime time->string => "Sat Jan 14 02:40:28 CET 2012" time ( -- r ) Returns real time, a ficlFloat. See gettimeofday(2) for more infor- mation. time->string ( secs -- str ) Converts ficl2Unsigned secs in a date string in local time. current-time time->string => "Sat Jan 14 02:40:28 CET 2012" time-reset ( -- ) Sets global timeval struct variable to current time. See gettimeofday(2) for more information. utime ( -- utime stime ) Returns user and system time as ficlFloats. See times(3) for more information. utime => 0.171875 0.0234375 System Words closelog ( -- ) Closes the log file. Syslog works without using closelog. See closelog(3) and syslog(3) for more information. environ ( -- hash ) Returns hash of all shell environment variables and their values. errno ( -- n ) Returns the error number set by several library functions. exec ( cmd -- ) Replaces the current process by running cmd as shell command. If cmd is a string, shell expansion takes place and if either FTH_POPEN_SHELL or SHELL is set to a shell pathname, use this shell, otherwise use /bin/sh to execute cmd. If cmd is an array of strings, no shell expansion takes place and the first element of cmd should be a program name. See exec(3) for more information. \ string lambda: <{}> "man exec" exec ; fork 0 waitpid exit-status 0= \ array of strings lambda: <{}> #( "man" "exec" ) exec ; fork 0 waitpid exit-status 0= fork ( xt -- pid ) Creates a new process and executes xt in the child. Fork returns child's process id to the parent process. See fork(2) for more in- formation. lambda: <{}> "man fork" exec ; fork 0 waitpid exit-status 0= getegid ( -- id ) Returns effective group id of calling process. See getegid(2) for more information. getenv ( name -- value ) Returns contents of shell environment variable name as string or #f if variable is not defined. See getenv(3) for more information. geteuid ( -- id ) Returns effective user id of calling process. See geteuid(2) for more information. getgid ( -- id ) Returns real group id of calling process. See getgid(2) for more in- formation. gethostname ( -- str ) alias: hostname Returns name of current host, see gethostname(3) for more informa- tion. getlogin ( -- str ) Returns name of user associated with current session. See getlogin(2) for more information. getpgrp ( -- pgrp ) Returns process group of current process. See "tcgetpgrp" and getpgrp(2) for more information. getpid ( -- id ) Returns process id. See getpid(2) for more information. getppid ( -- id ) Returns parent process id. See getppid(2) for more information. getrusage ( -- ary ) .getrusage ( -- ) Returns an array of 16 elements with all slots of struct rusage, see getrusage(2). .getrusage prints this array. getsid ( pid -- sid ) Returns session id for pid. If pid is 0, the session ID of the call- ing process is returned. See getsid(2) for more information. getuid ( -- id ) Returns real user id of calling process. See getuid(2) for more in- formation. kill ( pid sig -- ) Sends signal sig to process ID pid. If pid is zero, sends sig to current process. sig is a number or a constant like SIGKILL. See kill(2) for more information. openlog ( ident logopt facility -- ) Opens syslog for more specialized processing of the messages sent by syslog. Syslog works without using openlog. All constants for logopt and facility provided by syslog.h are available. See openlog(3), syslog(3) as well as "syslog" below for more information. putenv ( name value -- ) alias: setenv Sets value to shell environment variable name. See setenv(3) for more information. setegid ( id -- ) Sets effective group id. See setegid(2) for more information. seteuid ( id -- ) Sets effective user id. See seteuid(2) for more information. setgid ( id -- ) Sets real group id. See setgid(2) for more information. sethostname ( str -- ) Sets name of current host to str. See sethostname(3) for more infor- mation. setsid ( -- sid ) Creates a new session. The calling process is the session leader. See setsid(2) for more information. setuid ( id -- ) Sets real user id. See setuid(2) for more information. signal ( sig xt -- old-xt ) Installs xt for signal sig as an signal handler and returns old han- dler. XT must take one value from the stack, the signal, and should not return any value; its stack effect is ( sig -- ). See signal(3) for more information. SIGINT lambda: { sig -- } "\nSIGINT (#%d) received\n" '( sig ) fth-stderr ; signal value old-xt sleep ( secs -- ) Pauses for secs seconds. See sleep(3) for more information. strerror ( n -- str ) Returns the error message string corresponding to errno n, see strerror(3) for more information. strsignal ( n -- str ) Returns the signal description string corresponding to n, see strsignal(3) for more information. syslog ( priority fmt :optional args -- ) Writes messages built from fmt and corresponding formatting args to the system message logger. The fmt is identical to printf(3) format string, except that `%m' is replaced by the current error message from errno. The priority is one of the following constants: LOG_EMERG Panic condition. LOG_ALERT Corrupted system database etc. LOG_CRIT Critical condition (hard device error etc). LOG_ERR Errors. LOG_WARNING Warnings. LOG_NOTICE Not an error. LOG_INFO Information. LOG_DEBUG Debugging. See syslog(3) for more information. tcgetpgrp ( fd -- pgrp ) Returns process group id of foreground process group associated with the terminal device. Returns an invalid number if there is no fore- ground process group. One can use the following test to check if the process runs in fore- or background. See "getpgrp" and tcgetpgrp(3) for more information. getpgrp STDOUT_FILENO tcgetpgrp = if => foreground process else => background process then umask ( :optional mask nil -- mask ) Returns the current file mode creation mask if mask was not specified or sets the file mode creation mask to mask. You can specify the mask octal with `0o022', this is zero letter o zero two two. See umask(2) for more information. uname ( -- hs ) .uname ( -- ) Returns hash with five slots containing entries from uname(3) and .uname prints these slots. wait ( -- pid ) Waits for child process and returns its process ID. Sets global read only variable exit-status to the exit status of the exec-process. See wait(2) for more information. lambda: <{}> #( "man" "wait" ) exec ; fork value pid wait pid = if ." finished" then waitpid ( pid flags -- ) Waits for child process pid. Sets global read only variable exit-status to the exit status of the exec-process. flags may be 0 or one or more of the following POSIX constants ored together: WNOHANG Do not block. WNOWAIT Keep process in waitable state. See waitpid(2) for more information. lambda: <{}> #( "man" "waitpid" ) exec ; fork 0 waitpid exit-status 0= Getopt Variables optarg Getopt sets this variable to the option string of an argument which accepts options. opterr If #t, the default, getopt print error message in case of an error, if #f, no message will be printed. optind Getopt sets this variable to the index of the next element of the *argv* array. optopt If getopt finds unknown options or getopt misses required ar- guments, it stores that option in this variable. Getopt Words getopt ( argv opts -- c ) Returns next character from command line options. Here is the exam- ple from getopt(3) in Forth: % cat getopt-test.fth #! /usr/pkg/bin/fth -s : main ( -- ) #f { bflag } #f { ffile } #t to opterr \ getopt prints error messages begin *argv* "bf:" getopt ( ch ) dup while ( ch ) case <char> b of #t to bflag endof <char> f of optarg to ffile endof <char> ? of "usage: [-b] [-f file]\n" .stderr 1 (bye) \ exit with return code 1 endof endcase repeat ( ch ) drop optind 0 ?do *argv* array-shift drop loop *argv* array-length to *argc* "-b: %s, -f: %s\n" #( bflag ffile ) fth-print ; main 0 (bye) \ exit with return code 0 % ./getopt-test.fth => -b: #f, -f: #f % ./getopt-test.fth -b => -b: #t, -f: #f % ./getopt-test.fth -bf outfile => -b: #t, -f: outfile % ./getopt-test.fth -f => fth: option requires an argument -- f => usage: [-b] [-f file] % ./getopt-test.fth -h => fth: illegal option -- h => usage: [-b] [-f file] getopt-long ( argv opts longopts -- c ) Returns next character from command line options. : long-test #f { bflag } #f { ffile } #f to opterr #( #( "flag" no-argument <char> b ) #( "file" required-argument <char> f ) ) { opts } begin *argv* "bf:" opts getopt-long ( ch ) dup while ( ch ) case <char> b of #t to bflag endof <char> f of optarg to ffile endof <char> ? of "-%c requires an argument" #( optopt ) fth-warning endof endcase repeat drop ( ch ) optind 0 ?do *argv* array-shift drop loop *argv* array-length to *argc* "-b, --flag (default #f): %s\n" #( bflag ) fth-print "-f, --file (default #f): %s\n" #( ffile ) fth-print ; System Information And Exit (bye) ( n -- ) The exit hook "fth_exit_hook" will be called if set, all procs regis- tered for at-exit will be executed and the current process will be terminated with exit code n. _exit! ( n -- ) No exit hooks or at-exit words will be called, it calls _exit(2) with exit code n. at-exit ( obj -- ) obj, an proc-or-xt, will be called by Fth's exit function. More than one calls to at-exit are possible, all procs or xts will be called in order. The stack effect of obj is ( -- ). See atexit(3) for more information. lambda: <{ -- }> "test.file" file-delete ; at-exit .cflags ( -- ) config-cflags ( -- str ) Prints or returns compiler flags to compile libfth.so for use with other applications. See "EXAMPLES". .libs ( -- ) config-libs ( -- str ) Prints or returns linker flags to link libfth.so to other applica- tions. See "EXAMPLES". .long-version ( -- ) .version ( -- ) Prints long and short package version. .memory ( -- ) Prints used and free dictionary cells. .prefix ( -- ) config-prefix ( -- str ) Prints or returns installation prefix path. configure-args ( -- str ) Returns configure arguments. ver ( -- addr len ) Returns fth-version as a Forth string with addr len. ver type => "1.4.2 (2020/11/20) [x86_64-pkgsrc-netbsd]" Numbers bignum? complex? even? exact? fixnum? float? inexact? inf? integer? long-long? nan? number? odd? prime? ratio? rational? ulong-long? unsigned? #t if a given object is of corresponding type, ( obj -- f ). Comparison 0< 0<> 0> 0<= 0= 0>= negative? zero? positive? Compare ficlInteger with zero, ( n -- f ). < <> > <= = >= Compare two ficlInteger numbers, ( n1 n2 -- f ). u< u<> u> u<= u= u>= Compare two ficlUnsigned numbers, ( u1 u2 -- f ). d0< d0<> d0> d0<= d0= d0>= dnegative? dzero? dpositive? Compare a ficl2Integer with zero, ( d -- f ). d can be any type of number but should fit in ficl2Integer. 1 d0>= => #t 1.0 d0< => #f d< d<> d> d<= d= d>= Compare two ficl2Integers, ( d1 d2 -- f ). d1 and d2 can be any type of number but should fit in ficl2Integer. 1 2.0 d< => #t 1.0 2 d= => #f du< du<> du> du<= du= du>= Compare two ficl2Unsigned numbers, ( ud1 ud2 -- f ). ud1 and ud2 can be any type of number but should fit in ficl2Unsigned. 1 2.0 du< => #t 1.0 2 du= => #f c0<> c0= Compare ficlComplex with zero, ( c -- f ). c can be any type of num- ber but should fit in ficlComplex. 1.0+1.0i c0<> => #t 0.0+0.0i c0= => #t 1 c0= => #f c<> c= Compare two ficlComplex numbers, ( c1 c2 -- f ). c1 and c2 can be any type of number but should fit in ficlComplex. 1.0+1.0i 1+i c= => #t 1+0i 2.0 c<> => #t 1 1+0i c= => #t b0< b0<> b0> b0<= b0= b0>= Compare ficlBignum with zero, ( b -- f ) b can be any type of number. b< b<> b> b<= b= b>= Compare two ficlBignum numbers, ( b1 b2 -- f ). b1 and b2 can be any type of number. q0< q0<> q0> q0<= q0= q0>= Compare ficlRatio with zero, ( q -- f ). q can be any type of num- ber. q< q<> q> q<= q= q>= Compare two ficlRatio numbers, ( q1 q2 -- f ). q1 and q2 can be any type of number. Conversion Between Number Types f>s ( x -- n ) aliases: d>s c>s b>s q>s Converts any number to ficlInteger. s>d ( x -- d ) aliases: f>d >llong make-long-long Converts any number to ficl2Integer. s>ud ( x -- ud ) aliases: f>ud make-ulong-long Converts any number to ficl2Unsigned. s>f ( x -- r ) aliases: d>f c>f b>f q>f Converts any number to ficlFloat. s>c ( x -- c ) aliases: f>c q>c >c Converts any number to ficlComplex. s>b ( x -- b ) aliases: f>b >bignum make-bignum Converts any number to ficlBignum. s>q ( x -- q ) aliases: f>q c>q Converts any number to ficlRatio. Arithmetic 1+ 1- 2+ 2- 2* 2/ abs negate One argument ficlInteger operators, ( n1 -- n2 ). + - * / max min Two argument ficlInteger operators, ( n1 n2 -- n3 ). d2* d2/ dabs dnegate One argument ficl2Integer operators, ( d1 -- d2 ). d1 can be any type of number but should fit in ficl2Integer (not ficlBignum). d+ d- d* d/ dmax dmin Two argument ficl2Integer operators, ( d1 d2 -- d3 ). d1 and d2 can be any type of number but should fit in ficl2Integer (not fi- clBignum). 1/f f2* f2/ fabs fnegate One argument ficlFloat operators, ( r1 -- r2 ). r1 can be any type of number but should fit in ficlFloat. f+ f- f* f/ fmax fmin f** alias: fpow Two argument ficlFloat operators, ( r1 r2 -- r3 ). r1 and r2 can be any type of number but should fit in ficlFloat. facos ( r1 -- r2 ) facosh ( r1 -- r2 ) falog ( r1 -- r2 ) fasin ( r1 -- r2 ) fasinh ( r1 -- r2 ) fatan ( r1 -- r2 ) fatan2 ( r1 r2 -- r3 ) fatanh ( r1 -- r2 ) fceil ( r1 -- r2 ) fcos ( r1 -- r2 ) fcosh ( r1 -- r2 ) fexp ( r1 -- r2 ) fexpm1 ( r1 -- r2 ) flog ( r1 -- r2 ) flog10 ( r1 -- r2 ) flog2 ( r1 -- r2 ) flog1p ( r1 -- r2 ) alias: flogp1 floor ( r1 -- r2 ) fround ( r1 -- r2 ) fsin ( r1 -- r2 ) fsincos ( r1 -- r2 r3 ) fsinh ( r1 -- r2 ) fsqrt ( r1 -- r2 ) ftan ( r1 -- r2 ) ftanh ( r1 -- r2 ) ftrunc ( r1 -- r2 ) Math library words for real numbers. fsincos returns sin(r1) and cos(r1). r1 can be any type of number but should fit in ficlFloat. 1/c cnegate One argument ficlComplex operators, ( c1 -- c2 ). c1 can be any type of number but should fit in ficlComplex. c+ c- c* c/ c** alias: cpow Two argument ficlComplex operators, ( c1 c2 -- c3 ). c1 and c2 can be any type of number but should fit in ficlComplex. Complex-I ( -- I ) cabs ( c1 -- c2 ) cabs2 ( c1 -- c2 ) cacos ( c1 -- c2 ) cacosh ( c1 -- c2 ) carg ( c1 -- c2 ) casin ( c1 -- c2 ) casinh ( c1 -- c2 ) catan ( c1 -- c2 ) catan2 ( c1 c2 -- c3 ) catanh ( c1 -- c2 ) ccos ( c1 -- c2 ) ccosh ( c1 -- c2 ) cexp ( c1 -- c2 ) clog ( c1 -- c2 ) clog10 ( c1 -- c2 ) conj ( c1 -- c2 ) conjugate ( c1 -- c2 ) csin ( c1 -- c2 ) csinh ( c1 -- c2 ) csqrt ( c1 -- c2 ) ctan ( c1 -- c2 ) ctanh ( c1 -- c2 ) magnitude ( c1 -- c2 ) Math library words for complex numbers. c1 can be any type of number but should fit in ficlComplex. b2* b2/ babs bnegate One argument ficlBignum operators, ( b1 -- b2 ). b1 can be any type of number. b+ b- b* b/ b** alias: bpow bmax bmin Two argument ficlBignum operators, ( b1 b2 -- b3 ). b1 and b2 can be any type of number. bgcd ( x y -- z ) Greatest common divisor. x and y can be any type of number, z is of type ficlBignum. blcm ( x y -- z ) Least common multiple. x and y can be any type of number, z is of type ficlBignum. broot ( b1 u -- b2 n ) Returns the integer part of root u of b1. On top of stack is 1 if result is exact, otherwise 0. bsqrt ( b1 -- b2 n ) Returns the integer part of the square root of b1. On top of stack is 1 if result is exact, otherwise 0. bmod ( b1 b2 -- b3 n ) b3 becomes b1 modulo b2. b/mod ( b1 b2 -- b3 b4 n ) Divides b1 by b2 where b3 becomes the remainder and b4 becomes the quotient. blshift ( b1 n -- b2 ) brshift ( b1 n -- b2 ) Shifts arbitrary precision number b1 n bits to left resp. right. b1 can be any type of number while n has to be an integer (ficlInteger). 1/q qabs qceil qfloor qnegate One argument ficlRatio operators, ( q1 -- q2 ). q1 can be any type of number. q+ q- q* q/ q** qpow Two argument ficlRatio operators, ( q1 q2 -- q3 ). q1 and q2 can be any type of number. Miscellaneous Math Words fegetround ( -- n ) fesetround ( n -- ) Returns or sets current floating-point rounding mode, one of: FE_TONEARES FE_DOWNWARD FE_UPWARD FE_TOWARDZERO See fenv(3), fegetround(3), and fesetround(3). >complex ( r1 r2 -- c ) alias: make-rectangular Return a complex object with real r1 and image r2. denominator ( x -- n ) Returns denominator of x or 1. exact->inexact ( x -- r ) Converts x to an inexact number. imag-ref ( x -- r ) alias: image-ref Image part of x. inexact->exact ( x -- n ) Converts x to an exact number. inf ( -- inf ) Returns Infinity. make-polar ( real theta -- c ) Returns a polar complex object from real and theta. make-ratio ( num den -- q ) Returns a new ratio object with numerator num and denominator den. nan ( -- NaN ) Returns Not-A-Number. numerator ( x -- n ) Returns numerator of x or 0. rationalize ( x err -- y ) Returns inexact number within err of x. real-ref ( x -- r ) Real part of x. Pseudo Randomize Numbers rand-seed-ref ( -- seed ) Returns contents of the seed variable fth_randx. rand-seed-set! ( seed -- ) Sets seed to the seed variable fth_randx. frandom ( r -- -r...+r ) Returns pseudo randomized value between -r and +r. random ( r -- 0.0..r ) Returns pseudo randomized value between 0.0 and r. Formatted Number Output These formatted number output words will by convention add a space af- ter the number: .r ( n1 n2 -- ) Prints integer n1 in a right-adjusted field of n2 characters. 17 3 .r => | 17 | bn. ( b -- ) Prints bignum number. 17.0 bn. => |17 | c. ( c -- ) Prints complex number c. 17.0+1.0i c. => |17.0+1.0i | d. ( d -- ) Prints (Forth) double d (ficl2Integer). 17 d. => |17 | d.r ( d n -- ) Prints (Forth) double d (ficl2Integer) in a right-adjusted field of n characters. 17 3 d.r => | 17 | f.r ( r n -- ) Prints float r with n digits after decimal point. 17.0 3 f.r => |17.000 | q. ( q -- ) Prints rational number. 17.0 q. => |17/1 | u.r ( u n -- ) Prints unsigned integer u in a right-adjusted field of n characters. 17 3 u.r => | 17 | ud. ( ud -- ) Prints (Forth) unsigned double ud (ficl2Unsigned). 17 ud. => |17 | ud.r ( ud n -- ) Prints (Forth) unsigned double ud (ficl2Unsigned) in a right-adjusted field of n characters. 17 3 ud.r => | 17 | uf.r ( r len-all len-after-comma -- ) Prints float r in a right-adjusted field of len-all characters with len-after-comma digits. 17.0 8 3 uf.r => | 17.000 | 17.0 8 2 uf.r => | 17.00 | Math Constants euler e (~2.71828) half-pi pi/2 (~1.5708) ln-ten log(10) (~2.30259) ln-two log(2) (~0.693147) pi pi (~3.14159) sqrt-two sqrt(2) (~1.41421) two-pi pi*2 (~6.28319) Object Type Misc backtrace ( -- ) alias: bt Prints last word list from stack frame to Ficl error output. frame-depth ( -- n ) alias: stack-level Internal global variable. Returns the current frame depth. object-print-length ( -- n ) set-object-print-length ( n -- ) Returns or sets the number of objects to print for arrays, lists, hashs, etc. Default value is 64. If n is negative, prints all ele- ments. Garbage Collection gc-marked? ( obj -- f ) gc-protected? ( obj -- f ) gc-permanent? ( obj -- f ) Return #t if obj is an instance and the mark/protected/permanent flag is set. New created objects have the mark flag set. gc-mark ( obj -- obj ) gc-unmark ( obj -- obj ) gc-protect ( obj -- obj ) gc-unprotect ( obj -- obj ) They mark or unmark obj to protect or unprotect it from garbage col- lection. gc-on ( -- #f ) gc-off ( -- #f ) gc-run ( -- ) gc-stats ( -- ) They turn garbage collection on or off, run garbage collection and print garbage collection statistics. gc-protected-objects ( -- ary ) gc-permanent-objects ( -- ary ) Return an array containing all protected or permanent objects. Object-Type And Instance Words instance-gen-ref ( obj -- gen ) instance-obj-ref ( obj -- gen ) instance-gen-ref returns the GEN-struct of obj, instance-obj-ref re- turns the OBJ-struct of obj, used for example by "make-object-type-from". instance? ( obj -- f ) instance-of? ( obj type -- f ) Return #t if obj is an instance resp. an instance of type. make-instance ( gen obj -- instance ) Returns new instance of object-type obj with gen struct wrapped in. make-object-type ( name -- object-type ) object-type? ( obj -- f ) make-object-type creates a new object-type name and adds name to the feature list, creates a constant fth-name of object-type and returns the new object-type name. The new created object-type can be used to bind words to it. object-type? checks if obj is an object-type. make-object-type-from ( name base -- object-type ) Creates a new object-type name derived from base and adds name to the feature list, creates a constant fth-name of object-type and returns the new object-type name. All object words defined by base are available and probably only a few have to be changed or added. object-type-ref ( obj -- struct ) Returns object struct of object-type obj. object-types ( -- ary ) Returns array containing all known object names. Object Set Words set-object->array ( xt obj -- ) set-object->string ( xt obj -- ) set-object-apply ( xt obj arity -- ) set-object-copy ( xt obj -- ) set-object-dump ( xt obj -- ) set-object-equal-p ( xt obj -- ) set-object-free ( xt obj -- ) set-object-inspect ( xt obj -- ) set-object-length ( xt obj -- ) set-object-mark ( xt obj -- ) set-object-value-ref ( xt obj -- ) set-object-value-set ( xt obj -- ) They set xt as object- xxx word to object-type obj. General Object Words .inspect ( obj -- ) object-inspect ( obj -- str ) object-dump ( obj -- str ) .inspect prints inspect string of obj while the other words return the inspect and dump string of obj. The dump string may be evaled to reinstate the object from a file. .object-name ( obj -- ) object-name ( obj -- name ) They return or print object-type name of obj. cycle-ref ( obj -- val ) cycle-set! ( obj value -- ) cycle-start! ( obj index -- ) cycle-start@ ( obj -- index ) cycle-start0 ( obj -- ) Return or set values at current cycle-index, return or set cycle-in- dex or set cycle-index to zero. Cycles through contents of obj from first to last entry and starts over at the beginning etc. first-ref ( obj -- val ) first-set! ( obj value -- ) second-ref ( obj -- val ) second-set! ( obj value -- ) third-ref ( obj -- val ) third-set! ( obj value -- ) last-ref ( obj -- val ) last-set! ( obj value -- ) Return or set the corresponding elements of obj. Raise out-of-range exception if length of obj is less than 1, 2, or 3. hash-id ( obj -- id ) object-id ( obj -- id ) hash-id returns hash id computed from string representation of obj. Objects with the same contents have the same id. object-id returns object id of obj, a uniq number. object->array ( obj -- ary ) object->string ( obj -- str ) Return obj as array or string. object-apply ( obj args -- result ) alias: apply Runs apply on obj with args as arguments. args can be an array of arguments or a single argument. The number of args must fit apply's definition. The next two examples require each 1 argument: fth_set_object_apply(vct_tag, vct_ref, 1, 0, 0); /* C */ <'> enved-ref fth-enved 1 set-object-apply \ Forth object-copy ( obj1 -- obj2 ) Returns copy of obj1. Copies any element if obj1 is an instance. object-debug-hook ( obj -- hook ) Returns the debug-hook member of obj if there is any. The hook has the stack effect ( inspect-string obj -- new-str ). Any object can set this hook. If set, it will be called on inspecting the object with the inspect string as first argument. If there are more than one hook procedures, all of them will be called fed with the new string previously returned. #( 0 1 ) value ary ary .inspect => #<array[2]: #<fixnum: 0> #<fixnum: 1>> ary object-debug-hook lambda: <{ str obj -- new-str }> "debug-inspect: %s" #( obj ) string-format ; add-hook! ary .inspect => #<debug-inspect: #( 0 1 )> ary object-debug-hook hook-clear ary .inspect => #<array[2]: #<fixnum: 0> #<fixnum: 1>> object-empty? ( obj -- f ) alias: empty? Returns #t if length of obj is zero, otherwise #f. object-equal? ( obj1 obj2 -- f ) alias: equal? Returns #t if obj1 and obj2 have equal contents, otherwise #f. object-index ( obj key -- index ) alias: index object-find ( obj key -- value ) alias: detect object-member? ( obj key -- f ) alias: member? Return the index, the element or #t if key is present in obj, other- wise -1 (index) or #f. object-length ( obj -- len ) alias: length Returns length of obj. object-range? ( obj index -- f ) alias: range? Returns #t if index is in range of obj, otherwise #f. object-ref ( obj index -- val ) object-set! ( obj index value -- ) They return or set value at index. If obj is of a type which can have multiple elements, an array for example, sets or returns value at index. If obj is of a type which consists of only one element, a fixnum for example, ignores index and returns obj itself and set does nothing. object-set+! ( obj index value -- ) object-set-! ( obj index value -- ) object-set*! ( obj index value -- ) object-set/! ( obj index value -- ) They do some math on the specified element. Value may be any number (ficlInteger, ficlFloat, ficlRatio or ficlComplex). object-sort ( obj cmp-xt -- ary ) alias: sort Converts obj to an array, sorts and returns it. cmp-xt compares two items A and B and should return a negative integer if A < B, 0 if A == B, and a positive integer if A > B. : numb-sort { val1 val2 -- n } val1 val2 < if -1 else val1 val2 > if 1 else 0 then then ; #( 6 2 8 1 ) <'> numb-sort object-sort => #( 1 2 6 8 ) Predicates boolean? ( obj -- f ) nil? ( obj -- f ) undef? ( obj -- f ) true? ( obj -- f ) false? ( obj -- f ) They return #t if obj is of the specified kind. xmobj? ( obj -- f ) Returns #t if obj is an XmObj object (snd/xm.c). It is a special Snd XM test, see snd(1) for more information. Port IO Object Type One can build its own in- and output ports with the help of make-soft-port words. For example one can split the output to the snd(1) listener and to standard error or to a log file. Input Example "in-test.text" io-open-read value *io* :port-name "read-soft" :read-line lambda: <{ -- line }> *io* io-read ; :close lambda: <{ -- }> *io* io-close ; make-soft-input-port value prt prt port-read => first line of in-test.text prt port-close Output example The output is split to the Snd listener with snd-print and to standard error with .stderr. snd-print returns its input string which we use for .stderr. Nothing have to be closed and a :close proc isn't neces- sary. :port-name "sndout" :write-line lambda: <{ line -- }> line snd-print ( line ) .stderr ; make-soft-output-port value prt prt "hello" port-write make-soft-port ( :key args -- prt ) make-soft-input-port ( :key args -- prt ) make-soft-output-port ( :key args -- prt ) Returns new soft port IO object for reading or writing. The words above know the following keywords. Not all procs are re- quired. :fam r/o (default) | w/o | r/w :port-name "soft-port" :read-char ( -- c ) :read-line ( -- line ) :write-char ( c -- ) :write-line ( line -- ) :flush ( -- ) :close ( -- ) The prt argument in the following words may be an IO object returned from io- or port-words, or #f. In the latter case uses Ficl input resp. Ficl output. port->string ( prt -- str ) Returns entire contents of prt IO object as string if available. port-close ( prt -- ) port-flush ( prt -- ) Flush or close prt. If prt is #f, do nothing. port-closed? ( prt -- f ) Returns #t if prt IO object is closed, otherwise #f. port-display ( prt obj -- ) Writes string representation of obj to prt IO object. port-getc ( prt -- c ) port-gets ( prt -- str ) alias: port-read Return next character or next line from prt IO object. port-input? ( obj -- f ) port-output? ( obj -- f ) Returns #t if obj is an in- or output IO object or #f for Ficl in- and output, otherwise #f. port-putc ( prt c -- ) port-puts ( prt str -- ) alias: port-write Write character or string to prt IO object. port-puts-format ( prt fmt args -- ) alias: port-write-format Writes formatted string to prt IO object. For example, write "hello, world" to Ficl output (#f): #f "hello, %s" #( "world" ) port-puts-format => hello, world port? ( obj -- f ) Returns #t if obj is an IO object or #f for Ficl in- and output, oth- erwise #f. With-In|Output-Port The following words recognize these keywords: :filename filename Opens file IO connected to filename with one of the access modes: :fam r/o | w/o | r/w :command command | array-of-strings Opens pipe IO connected to command or an array of strings in the form of #( "ls" "-l" ) with one of the access modes: :fam r/o | w/o | r/w :string string Opens string IO connected to string with one of the access modes: :fam r/o | w/o | r/w :socket hostname Opens socket IO connection with one or more of these additional key- words and access modes: :fam r/w | server :domain domain (default AF_INET6) :port port (default 1024) :type type (default SOCK_STREAM) :soft-port string Opens soft port IO with one or more of these additional keywords and access modes: :fam r/o | w/o | r/w :port-name "soft-port" :read-char ( -- c ) :read-line ( -- line ) :write-char ( c -- ) :write-line ( line -- ) :flush ( -- ) :close ( -- ) with-input-port ( obj :key args -- str ) obj ( io -- str ) with-input-from-port ( obj :key args -- str ) obj ( -- str ) Open IO object for input, read or execute obj and close the IO ob- ject. with-input-from-port points the input IO to *stdin*. If the obj argument for input is nil, read the entire IO object, other- wise execute obj as a proc-or-xt. After reading is finished close IO object and return resulting string. lambda: <{ io -- str }> io io->string ; :filename "file.test" with-input-port <'> io-readlines :command "ls -l" with-input-port nil :string "hello" with-input-port lambda: <{ -- str }> *stdin* io->string ; :filename "file.test" with-input-from-port nil :command "ls -l" with-input-from-port nil :string "hello" with-input-from-port with-output-port ( obj :key args -- ) obj ( io -- ) with-output-to-port ( obj :key args -- ) obj ( -- ) with-error-to-port ( obj :key args -- ) obj ( -- ) Open IO object for output, write or execute obj and close the IO ob- ject. with-output-to-port points the output IO to *stdout* and with-error-to-port points it to *stderr*. If the obj argument for output is a string, write the string to the IO object, if obj is an array, write its contents to the IO object, other- wise execute obj as a proc-or-xt. After writing is finished close IO object. "hello" :filename "file.test" with-output-port "file.test" readlines :command "cat" with-output-to-port "" value s lambda: <{ io -- }> io "hello" io-write ; :string s with-output-port lambda: <{ -- }> \ all three do the same and put the string to *stdout*: \ *stdout* "hello" io-write \ #f "hello" port-write ." hello" ; :string s with-output-to-port lambda: <{ -- }> *stderr* "hello" io-write ; :string s with-error-to-port Procs And Xts .proc ( prc -- ) Prints Proc object prc to current output. <'set> ( "name" -- set-name|#f ) Parses name and searches for word set-name. Returns xt of set-name if found. See also "set!", "set-execute" and "set-xt". The follow- ing two lines do the same: 128 <'set> object-print-length execute 128 set-object-print-length <{ ( -- ) Turns current colon definition in a Proc object. Takes tokens up to closing `}>' as local variables, `--' starts a comment ignoring the rest to closing `}>'. In addition to other local variable words like { } and {{ }} this form handles two keywords, :key and :optional. Variable names are taken from keyword and optional names. This word can span over more than one lines but without empty lines or comments in between. If :key and :optional is used together, :key must come first. All keyword and optional variables must have default values. This word is immediate and compile only and can only be used in word definitions. : optkey-test <{ a b c :key d 10 e 20 :optional f 30 g 40 -- ary }> #( a b c d e f g ) ; 1 2 3 optkey-test => #( 1 2 3 10 20 30 40 ) :d 11 1 :e 22 2 3 4 optkey-test => #( 1 2 3 11 22 4 40 ) <{}> ( -- ) Turns current colon definition in a Proc object. This word is imme- diate and compile only and can only be used in word definitions. : we-dont-need-args <{}> ; <'> we-dont-need-args proc? => #t defined? ( "name" -- f ) Returns #t if name is defined in the dictionary. defined? 10 => #f defined? nil => #t defined? + => #t doc" ( <ccc>" -- ) Adds input buffer up to next double quote character `"' to the docu- mentation of current word. Escape double quote character with back- slash if required in documentation. It is not necessary to repeat the stack effect if it already exists in the word definition. This word is immediate and compile only and can only be used in word defi- nitions. : new-word ( -- ) doc" our documentation may contain \ \"double quotes\". Escape them with a backslash." \ we do nothing ; help new-word => new-word ( -- ) our documentation may contain "double quotes". Escape them with a backslash. documentation-ref ( obj -- str ) Returns documentation string of obj (Forth word, object or topic) or #f. documentation-set! ( obj str -- ) Sets documentation of any obj (Forth word, object or topic) to str. get-func-name ( -- name ) Returns name of current xt in word definition as string. This word is immediate and compile only and can only be used in word defini- tions. : new-word get-func-name .$ space 10 ; new-word => new-word 10 get-optarg ( req def -- val ) Returns either default value def or a value found on top of stack. req is the sum of required and following optional arguments. It sim- ulates the :optional keyword in Lisp/Scheme. : optarg-test ( a b c=33 d=44 e=55 -- ary ) 4 55 get-optarg { e } 3 44 get-optarg { d } 2 33 get-optarg { c } { a b } #( a b c d e ) ; 1 2 optarg-test => #( 1 2 33 44 55 ) 1 2 3 4 optarg-test => #( 1 2 3 4 55 ) 1 2 3 4 5 6 7 optarg-test => 1 2 #( 3 4 5 6 7 ) get-optargs ( lst req -- vals ) The plural form of get-optarg. args is an array with default values, req is the number of required arguments. Returns req + args length values on stack, either default ones or from stack. : optargs-test ( a b c=33 d=44 e=55 -- ary ) #( 33 44 55 ) 2 get-optargs { a b c d e } #( a b c d e ) ; 1 2 optargs-test => #( 1 2 33 44 55 ) 1 2 3 4 optargs-test => #( 1 2 3 4 55 ) 1 2 3 4 5 6 7 optargs-test => 1 2 #( 3 4 5 6 7 ) get-optkey ( key def -- val ) Returns either default value def or a value found on stack specified by keyword key. It simulates the :key keyword in Lisp/Scheme. : optkey-test ( start dur keyword-args -- ary ) :frequency 440.0 get-optkey { freq } :initial-phase pi get-optkey { phase } { start dur } #( start dur freq phase ) ; 0 1 optkey-test => #( 0.0 1.0 440.0 3.14159 ) 0 2 :frequency 330.0 optkey-test => #( 0.0 2.0 330.0 3.14159 ) get-optkeys ( ary req -- vals ) The plural form of get-optkey. ary is an array of key-value pairs, req is the number of required arguments. Returns req + ary length / 2 values on stack, either default ones or from stack. : optkeys-test ( start dur keyword-args -- ary ) #( :frequency 440.0 :initial-phase pi ) 2 get-optkeys { start dur freq phase } #( start dur freq phase ) ; 0 1 optkeys-test => #( 0.0 1.0 440.0 3.14159 ) 0 2 :frequency 330.0 optkeys-test => #( 0.0 2.0 330.0 3.14159 ) help ( "name" -- ) Returns documentation of name (Forth word or topic) or "no documenta- tion available". help make-array \ Forth word help array \ topic help-add! ( obj str -- ) Appends str to documentation of obj (Forth word, object or topic). help-ref ( obj -- str ) Returns documentation of obj (Forth word, object or topic) or "no documentation available". help-set! ( obj str -- ) Sets documentation of obj (Forth word, object or topic) to str. #( "behemoth" "pumpkin" "mugli" ) value hosts hosts "local-net hostnames" help-set! hosts help-ref => "local-net hostnames" lambda: ( -- xt ) Starts nameless word definition and sets variable latestxt to xt. Stack-effect or normal comments immediately at the beginning will be used as documentation. Returns xt (after the closing semicolon `;'). lambda: ( a b -- c ) + ; value plus plus help-ref => lambda: ( a b -- c ) 1 2 plus execute => 3 1 2 lambda: ( a b -- c ) * ; execute => 2 latestxt ( -- xt ) Returns latest defined xt. local-variables ( -- vars ) Returns a hash of local variable name-value pairs up to the location in the definition. This word is immediate and compile only and can only be used in word definitions. : word-with-locals { foo -- } 10 { bar } local-variables each .$ space end-each ; 20 word-with-locals => #{ "bar" => 10 "foo" => 20 } make-proc ( xt arity -- prc ) Returns new Proc object. arity can be an integer or an array of length 3, #( req opt rest ). <'> + 2 make-proc => + lambda: ( a b -- c ) + ; #( 2 0 #f ) make-proc => lambda-009 proc->xt ( prc -- xt ) Returns the actual word (the execution token xt) of prc. proc-apply ( prc args -- res ) alias: run-proc Executes Proc object prc with arguments args and returns result or #f. args can be an array of arguments or a single argument. If exe- cution fails, raises eval-error exception, if length of args is less than the required arity of prc, raises bad-arity exception. <'> + 2 make-proc value plus plus #( 5 6 ) proc-apply => 11 proc-arity ( prc -- arity ) Returns arity array #( req opt rest ) of Proc object prc, or #f if not a Proc object. proc-create ( arity -- prc ) Returns nameless Proc object with arity. Like create it goes with does>. : input-fn ( gen -- proc; dir self -- r ) { gen } 1 proc-create \ returns proc with one argument gen , \ stores gen for later use in DOES does> { dir self -- r } \ dir (ignored here) self (address) self @ \ returns our gen readin \ returns readin value ; instrument: src-simp <{ start dur amp sr sr-env fname -- }> :file fname find-file make-readin { f } :input f INPUT-FN :srate sr make-src { sc } :envelope sr-env :duration dur make-env { en } start dur run i sc en env #f src amp f* *output* outa drop loop f mus-close drop ;instrument 0 1.5 0.5 0.2 #( 0 0 50 1 100 0 ) "fyow.snd" <'> src-simp with-sound proc-name ( prc -- name ) Returns name of Proc object prc if found. proc-source-ref ( proc-or-xt -- str ) Returns source string of proc-or-xt, or #f if not available. proc-source-set! ( prc str -- ) Sets source string of prc to str. proc? ( obj -- f ) Returns #t if obj is a Proc object. running-word ( -- xt ) Returns current xt in word definition. This word is immediate and compile only and can only be used in word definitions. : new-word running-word xt->name .$ space 10 ; new-word => new-word 10 see2 ( "name" -- ) Shows word definition of name. set! ( "name" -- ) Parses name and executes word set-name if found, otherwise raises undefined-word exception. The following two lines do the same: 128 set! object-print-length 128 set-object-print-length set-execute ( xt -- ?? ) Executes set-xt if found, otherwise raises undefined-word exception. The following two lines do the same: 128 <'> object-print-length set-execute 128 set-object-print-length set-xt ( xt1 -- xt2 ) Returns set-xt if found. The following two lines do the same: 128 <'> object-print-length set-xt execute 128 set-object-print-length source-file ( xt -- file ) Returns source file where xt was created or #f if a C-primitive or not defined. source-line ( xt -- line ) Returns source line number where xt was created or #f if a C-primi- tive or not defined. source-ref ( obj -- str ) Returns source string of obj, a proc or xt, or #f if not found. source-set! ( obj str -- ) Sets source string of obj, a proc or xt, to str. thunk? ( obj -- f ) Returns #t if obj is a Proc object with arity #( 0 0 #f ). trace-var ( var proc-or-xt -- ) Installs a hook on the specified global variable and adds proc-or-xt with stack effect ( val -- res ). The hook will be executed after every variable set via to. mus-array-print-length => 8 8 value *clm-array-print-length* <'> *clm-array-print-length* lambda: <{ val -- res }> val set-mus-array-print-length ; trace-var 24 to *clm-array-print-length* *clm-array-print-length* => 24 mus-array-print-length => 24 <'> *clm-array-print-length* untrace-var untrace-var ( var -- ) Removes previously installed hook from var. word? ( obj -- f ) Returns #t if obj is a Proc object or an xt (execution token, address of a Ficl word). word-create ( name -- ) Creates word name in dictionary with does> -part as body. : make-setter ( name -- ; hs val self -- ) { name } name "!" $+ word-create name , does> { hs val self -- } hs self @ ( slot ) val hash-set! ; "user-time" make-setter => creates setter word 'user-time!' #{} value hs hs 3.2 user-time! hs => #{ "user-time" => 3.2 } name->xt ( name -- xt ) Returns execution token xt of name if found. 1 2 "+" name->xt execute => 3 xt->name ( xt -- str ) Returns name of xt if found. <'> + xt->name => "+" xt->origin ( xt -- str ) Returns name, source file and source line number where xt was defined as string (name:file:line). If xt is a C-primitive, returns (name:primitive), if not defined, returns an empty string. xt? ( obj -- f ) Returns #t if obj is an xt (execution token, address of a Ficl word). Regexp Object Type General help for regexp can be found in regex(3) and re_format(7). For all matching words below, matched results or #f are stored in the Reg- exp object reg. The last match results are also stored in the read- only variables "*re*" and "*re0*" to "*re9*". *re-syntax-options* This is the cflag option of regcomp(3), default REG_EXTENDED. The variable can be set with the following predefined constants, if more than one are used, combine them with or: REG_BASIC REG_EXTENDED REG_ICASE REG_NOSUB REG_NEWLINE REG_NOSPEC REG_PEND For example, set matching to ignore case before creating a new reg- exp: REG_EXTENDED REG_ICASE or to *re-syntax-options* *re-exec-options* This is the eflag option of regexec(3). The variable can be set with the following predefined constants, if more than one are used, com- bine them with or: REG_NOTBOL REG_NOTEOL REG_STARTEND No default is set. / ( <ccc>/ -- reg ) The prefix character `/' starts a regular expression object delimited by a second `/'. /(B|b)+/ => /(B|b)+/ make-regexp ( str -- reg ) Returns a new Regexp object from str which may contain regular ex- pressions. "(B|b)+" make-regexp value reg re-match ( reg str start -- n ) Searches reg in str from start and returns first match's length or -1 if no match was found. /b+/ "aabaab" 0 re-match => 1 /b+/ "aabaac" 3 re-match => -1 re-search ( reg str start range -- n ) Searches reg in str from start for range characters and returns first match's position or -1 if no match was found. /b+/ "aabaab" 2 1 re-search => 2 /b+/ "aabaab" 0 1 re-search => -1 re/ ( space<ccc>/ -- reg ) Parses regexp ccc delimited by `/' at compile time and returns it at interpret time. See "/" for an alternative. re/ (B|b)+/ => /(B|b)+/ regexp-match ( reg str -- len|#f ) aliases regexp= re= Searches reg in str and returns first match's length or #f if no match was found. /.*(bar)/ value reg reg "foobar" regexp-match => 6 reg 0 apply => foobar reg 1 apply => bar reg 2 apply => #f regexp-replace ( reg str1 replace -- str2 ) Replaces first occurrence of reg in str1 with replace if found. Ref- erences \1 to \9 in replace will be replaced by corresponding subex- pressions. If there are no corresponding subexpressions, raises regexp-error exception. /(foo)/ "foo-bar" "***\\1***" regexp-replace => ***foo***-bar Note the double backslashes on back reference characters. regexp-search ( reg str :key start 0 range -1 -- pos|#f ) Searches reg in str from start for range characters and returns first match's position or #f if no match was found. If position is zero, returns #t to fool Forth' if. If keyword range is -1 (default), the entire string will be searched. /foo/ "foobar" :start 0 :range 6 regexp-search => #t (pos 0) /(bar)/ value reg reg "foobar" :start 0 :range 2 regexp-search => #f reg "foobar" :start 3 :range 2 regexp-search => 3 reg 0 apply => bar reg 1 apply => bar reg 2 apply => #f regexp? ( obj -- f ) Returns #t if obj is a Regexp object, otherwise #f. /^$/ regexp? => #t String Object Type Print Words .string ( obj -- ) aliases: .$ .g .error ( obj -- ) They print string representation of obj to Ficl output or Ficl error output. warning ( str -- ) alias: warn error ( str -- ) die ( str -- ) fth-warning ( fmt :optional args -- ) fth-error ( fmt :optional args -- ) fth-die ( fmt :optional args -- ) They print str or fmt string with corresponding args array to Ficl error output wrapped either in #<warning: ...> continuing execution, or in #<error: ...> and throw error-exit exception, or in #<die: ...> and exit the interpreter with return code 1 (EXIT_FAILURE); args is optional. See "string-format" for fmt description. fth-format ( fmt :optional args -- str ) Returns String object from fmt string and args array containing cor- responding arguments; args is optional. See "string-format" for fmt description. fth-read ( -- str ) Reads String object from Ficl input. fth-print ( fmt :optional args -- ) Prints fmt string with corresponding args array to Ficl output; args is optional. See "string-format" for fmt description. .stdout ( obj -- ) .stderr ( obj -- ) .debug ( obj -- ) fth-stdout ( fmt :optional args -- ) fth-stderr ( fmt :optional args -- ) fth-debug ( fmt :optional args -- ) They print the string representation of obj or a string built from fmt and optional array args to standard output (FILE *stdout) or standard error (FILE *stderr); .debug and fth-debug wrap output in #<DEBUG(F): ...>. Ficl output and standard output may differ as well as Ficl error output and standard error. String Create Words " ( <ccc>" -- str ) The prefix character `"' starts a String object delimited by a second `"'. "pumpkin" => "pumpkin" "" ( -- str ) Returns an empty String object. $" ( space<ccc>" -- str ) Parses string ccc delimited by `"' at compile time and returns it at interpret time. See """ for an alternative. $" pumpkin" => "pumpkin" $>string ( addr len -- str ) string>$ ( str -- addr len ) They convert between Forth strings and Fth String objects. Standard words like type and evaluate require this kind of strings. $cr ( -- str ) $space ( -- str ) $spaces ( n -- str ) They return the string representation of a carriage return, a single space or n spaces. int->char ( n -- c ) Takes integer n and returns it as character. If n is non-printable and vis(3) is available, vis(3) encodes it, otherwise, returns the integer. make-string ( len :key initial-element ' ' -- str ) Returns a new String object of length len filled with initial-element characters, default space. Raises out-of-range exception if len < 0. 3 :initial-element <char> x make-string => "xxx" string-format ( fmt args -- ) alias format fmt is a printf(3) format string and args, which may be an array, a single argument or #f, the required arguments. "%04d %8.2f %b %X %o" #( 128 pi 255 255 255 ) string-format => "0128 3.14 11111111 FF 377" The format string can have zero or more of the following flags: # The value will be converted to an alternate form. For b, B, o and O conversion, add a zero before the output, for x and X conversion, add a `0x' respective `0X' before the output. For a, A, e, E, f, F, g and G conversion, the result will always have a decimal point. - Flushes output left. 0 Padding with `0' (zero) rather than blank. The following conversion specifiers are known: % A `%' is written. aAeEfFgG Floating point output like printf(3). c Single character output. bdouxX Integer output in binary, decimal, octal, unsigned and hexadecimal form. p Inspect string output of any Fth object with object-inspect. s String representation of any Fth object with object->string. S m Dump string output of any Fth object with object-dump. General String Words char? ( obj -- ) Returns #t if obj is a character, otherwise #f. string->array ( str -- ary ) Converts str to an array of characters. "foo" string->array => #( 102 111 111 ) string-append ( str1 str2 -- str3 ) alias: $+ Returns new string from str1 + str2. string-capitalize ( str1 -- str2 ) string-capitalize! Returns changed or new String object with first character capitalized and remaining characters changed to lowercase. string-capitalize! changes the original string contents. string-chomp ( str1 -- str2 ) string-chomp! Returns changed or new String object with possible trailing `\n' re- moved. string-chomp! changes the original string contents. string-concat ( objs len -- str ) alias: >string Returns new String object with len objects from stack converted to their string representation. Raises out-of-range exception if len < 0. 0 1 2 " foo " "b" "a" "r" 7 >string => "012 foo bar" string-copy ( str1 -- str2 ) Returns a copy of str1. string-delete! ( str idx -- val ) Deletes and returns character at position idx from str; negative in- dex counts from backward. Raises out-of-range exception if index is not in range of str. string-downcase ( str1 -- str2 ) string-downcase! Returns changed or new String object with all characters changed to downcase. string-downcase! changes the original string contents. string-eval ( str -- ?? ) Evaluates str; values already on stack can be accessed, resulting values remain on stack. 7 "3 4 + +" string-eval => 14 string-eval-with-status ( str -- ?? status ) Evaluates str and returns eval-status on top of stack; values already on stack can be accessed, resulting values remain on stack. Eval- status can be one of the following constants: BREAK Ficl Break ERROR_EXIT Ficl Error Exit INNER_EXIT Ficl Inner Exit OUT_OF_TEXT Ficl Out of Text RESTART Ficl Restart USER_EXIT Ficl User Exit string-fill ( str char -- str' ) Fills str with char and returns changed String object. string-find ( str1 key -- str2|#f ) Returns from match on if string or regexp key exists in str, other- wise #f. "hello world" "l" string-find => "llo world" "hello world" /ell/ string-find => "ello world" string-index ( str key -- idx ) Returns index of string key in str or -1 if not found. "hello world" "orl" string-index => 7 string-insert! ( str idx val -- str' ) Inserts string representation of val to str at position idx; negative index counts from backward. Raises out-of-range exception if index is not in range of str. string-length ( str -- len ) If str is a String object, returns its length, otherwise -1. string-member? ( str key -- f ) Returns #t if string or regexp key exists in str, otherwise #f. "hello world" "ell" string-member? => #t "hello world" /ell/ string-member? => #t string-pop ( str -- char ) Removes and returns last character of str. If str is empty, returns #f. string-push ( str val -- str' ) alias: << Appends string representation of val to str and returns changed String object. string-ref ( str idx -- val ) Returns character at position idx; negative index counts from back- ward. Raises out-of-range exception if index is not in range of str. string-replace ( str1 from to -- str2 ) string-replace! Returns changed or new String object with string from replaced by string to. If to is the empty string, deletes the from part from str1. string-replace! changes the original string contents. string-reverse ( str1-- str2 ) string-reverse! Returns changed or new String object reversed. string-reverse! changes the original string contents. string-set! ( str idx val -- ) Stores character char at index idx; negative index counts from back- ward. Raises out-of-range exception if index is not in range of str. string-shift ( str -- char ) Removes and returns first character of str. If str is empty, returns #f. string-split ( str sep -- ary ) Splits str using sep as delimiter and returns result as array of strings. If sep is not a string or regexp, delimiter is " \t" (space and tab). "foo:bar:baz:" ":" string-split => #( "foo" "bar" "baz" ) "foo:bar:baz:" /:/ string-split => #( "foo" "bar" "baz" ) string-substring ( str1 start end -- str2 ) Returns new string from position start to, but excluding, position end. If end is not an integer, end will be set to length of str1; negative index counts from backward. Raises out-of-range exception if start is not in range of str1. "hello world" 2 4 string-substring => "ll" "hello world" 0 -1 string-substring => "hello world" "hello world" -4 -2 string-substring => "orl" "hello world" -4 nil string-substring => "orld" string-unshift ( str val -- str' ) Adds string representation of val in front of str and returns changed String object. string-upcase ( str1 -- str2 ) string-upcase! Returns changed or new String object with all characters changed to uppercase. string-upcase! changes the original string contents. string-cmp ( str1 str2 -- n ) Returns -1 if str1 is less than str2, 1 if str1 is greater than str2, and 0 if str1 is equal to str2. It may be used with sort word. string< ( str1 str2 -- f ) Returns #t if str1 is lexicographically lesser than str2. string<> ( str1 str2 -- f ) Returns #t if strings are not equal. string= ( str1 str2 -- f ) Returns #t if strings are equal. string> ( str1 str2 -- f ) Returns #t if str1 is lexicographically greater than str2. string? ( obj -- f ) Returns #t if obj is a String object, otherwise #f. Symbols Symbols are actually values (variables) named 'name. .symbol ( sym -- ) Prints symbol sym to current output. create-symbol ( "name" -- ) Creates symbol name with `'' (apostrophe) in front. create-symbol new-symbol => creates symbol 'new-symbol make-symbol ( name -- sym ) Creates and returns the new symbol name with `'' (apostrophe) in front. "new-symbol" make-symbol => 'new-symbol symbol-name ( sym -- str ) Returns the name of symbol sym as string. 'new-symbol symbol-name => "new-symbol" symbol= ( obj1 obj2 -- f ) Returns #t if obj1 and obj2 are symbols with identical names, other- wise #f. symbol? ( obj -- f ) Returns #t if obj is a symbol, otherwise #f. Keywords Keywords are actually values (variables) named :name. .keyword ( kw -- ) Prints keyword kw to current output. create-keyword ( "name" -- ) Creates keyword name with `:' in front. create-keyword new-keyword => creates keyword :new-keyword keyword-name ( kw -- name ) Returns the name of keyword kw as string. :new-keyword keyword-name => "new-keyword" keyword= ( obj1 obj2 -- f ) Returns #t if obj1 and obj2 are keywords with identical names, other- wise #f. keyword? ( obj -- f ) Returns #t if obj is a keyword, otherwise #f. make-keyword ( name -- kw ) Creates and returns the new keyword name with `:' in front. "new-keyword" make-keyword => :new-keyword Exceptions .exception ( ex -- ) Prints exception ex to current output. create-exception ( msg "name" -- ) Creates exception named name with message msg; msg may be #f. The exception has a symbol name, that means it has the prefix `'' before name. "New test exception" create-exception new-exception => creates 'new-exception exception-last-message-ref ( ex -- msg ) Returns last message of exception ex. The last message was set after an exception was thrown with for example "fth-throw" or "fth-raise". exception-last-message-set! ( ex msg -- ) Sets message msg, a string or #f, as the last message of exception ex. This will be set automatically after an exception was thrown with for example "fth-throw" or "fth-raise". exception-message-ref ( ex -- msg ) Returns the message of exception ex. exception-message-set! ( ex msg -- ) Sets message msg, a string or #f, to exception ex. exception-name ( ex -- name ) Returns the name of exception ex as string. 'new-exception exception-name => "new-exception" exception= ( obj1 obj2 -- f ) Returns #t if obj1 and obj2 are exceptions with identical names, oth- erwise #f. exception? ( obj -- f ) Returns #t if obj is an exception, otherwise #f. make-exception ( name msg -- ex ) Creates and returns the new exception named name with message msg; msg may be #f. The exception has a symbol name, that means it has the prefix `'' before name. "New test exception" create-exception new-exception => creates 'new-exception symbol->exception ( sym -- ex ) Returns symbol sym as exception. ENVIRONMENT fth reads the following global environment variables: FTH_DICTIONARY_SIZE Overwrites default dictionary size (1024 * 1024). FTH_LOCALS_SIZE Overwrites default number of locals (2048). FTH_RETURN_SIZE Overwrites default size of return stack (1024). FTH_STACK_SIZE Overwrites default size of parameter stack (8192). FTH_FTHPATH A colon separated list of paths pointing to Forth script files. These paths will be added in front of *load-path*. FTH_HISTORY Overwrites default history filename ~/.fth-history. FTH_HISTORY_LENGTH Overwrites default history file length (100). FTH_INIT_FILE Overwrites default initialization filename ~/.fthrc. FTH_LIBPATH A colon separated list of paths pointing to C extension libraries. These paths will be added in front of *load-lib-path*. FTH_POPEN_SHELL This variable can be set to a pathname of a shell. fth_popen() as well as exec, if cmd is a string, use this shell for execution of shell commands. If not defined, fth_popen() falls back to /bin/sh, and exec, if cmd is a string, falls back to SHELL or, if not set, /bin/sh. Furthermore, fth checks the following shell variables: HOME LOGNAME SHELL TMPDIR VERSION_CONTROL FILES fth uses a global and a local initialization file and a history file. ${prefix}/etc/fthrc Global initialization file for system wide configuration. ~/.fthrc Local initialization file for user configuration. The name can be changed with environment variable FTH_INIT_FILE. ~/.fth-history Local history file. The name can be changed with environment vari- able FTH_HISTORY. EXIT STATUS The fth utility exits 0 on success, and >0 if an error occurs. EXAMPLES Some examples of typical usage of the fth interpreter: Prints 32 Fahrenheit as Celsius (0.0): % fth -e "32 f2c . cr" The following loads the C extension library libxm.so with its initial- ization function Init_libxm() and the Forth source file motif-script.fs, executes word main and exits: % fth -S "libxm Init_libxm" -e "main" motif-script.fs Adds path ~/share/forth in front of *load-path*, loads Forth source file sound-script.fs and starts the repl. Initialization files ${prefix}/etc/fthrc and ~/.fthrc are loaded if they exist: % fth -I ~/share/forth sound-script.fs Prints compiler and linker flags for CFLAGS and LIBS: % fth -e .cflags % fth -e .libs % fth -e "config-cflags .g space config-libs .g cr" Runs Forth script check.fth and provides option -a and option -b with argument 10 to the script which should handle at least these two; exits if finished: % fth -s check.fth -ab 10 If the first line in check.fth is #! /usr/pkg/bin/fth -s and the script is made executable chmod 0755 check.fth the call above could be shortened to: % ./check.fth -ab 10 Prints name (column 1) and login time (column 5) from the who(1) com- mand output: who | fth -ane '.*1* .*5* cr' The same with output field separator set to " == ": who | fth -ane '" == " to *ofs* .*1* .*5* cr' Print login names and their uids found in /etc/passwd: cat /etc/passwd | fth -aF: -e '"%5s %s\n" #( *3* *1* ) fth-print' If the only option is a dash `-', fth reads from standard input and prints the result to standard output. The following examples print the same result (~26.7): % echo "80 f2c" | tee foo | fth - % cat foo | fth - % fth - < foo % fth - 80 f2c <enter> 26.66666666666667 bye % SEE ALSO tcsh(1), libfth(3), tecla(7). W. Richard Stevens, UNIX Network Programming, Prentice Hall, Englewood Cliffs, N.J., 1990. HISTORY This manual page describes fth version 1.4.5. fth is based on Ficl, Forth-inspired command language, version 4.0.31 written by John Sadler. AUTHORS fth and this manual page were written by Michael Scholz <mi-scholz@users.sourceforge.net>. BUGS Please report bugs to the author. FreeBSD ports 15.0 2025/01/22 FTH(1)
NAME | SYNOPSIS | DESCRIPTION | REFERENCE | ENVIRONMENT | FILES | EXIT STATUS | EXAMPLES | SEE ALSO | HISTORY | AUTHORS | BUGS
Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=fth&sektion=1&manpath=FreeBSD+Ports+15.0>
