Forth-94 introduced the idea of “environmental queries” as a way for a program running on a system to determine certain characteristics of the system. The Standard specifies a number of strings that might be recognised by a system, and a way of querying them:
environment?
( c-addr u – false / ... true ) core “environment-query”
c-addr, u specify a counted string. If the string is not
recognised, return a false
flag. Otherwise return a
true
flag and some (string-specific) information about
the queried string.
Note that, whilst the documentation for (e.g.)
ADDRESS-UNIT-BITS
shows it returning one cell on the stack,
querying it using environment?
will return an additional item;
the true
flag that shows that the string was recognised; so for
querying ADDRESS-UNIT-BITS
the stack effect of
environment?
is ( c-addr u -- n true )
.
Several environmental queries deal with the system’s limits:
ADDRESS-UNIT-BITS
( – n ) environment “ADDRESS-UNIT-BITS”
Size of one address unit, in bits.
MAX-CHAR
( – u ) environment “MAX-CHAR”
Maximum value of any character in the character set
/COUNTED-STRING
( – n ) environment “slash-counted-string”
Maximum size of a counted string, in characters.
/HOLD
( – n ) environment “slash-hold”
Size of the pictured numeric string output buffer, in characters.
/PAD
( – n ) environment “slash-pad”
Size of the scratch area pointed to by PAD
, in characters.
CORE
( – f ) environment “CORE”
True if the complete core word set is present. Always true for Gforth.
CORE-EXT
( – f ) environment “CORE-EXT”
True if the complete core extension word set is present. Always true for Gforth.
FLOORED
( – f ) environment “FLOORED”
True if /
etc. perform floored division
MAX-N
( – n ) environment “MAX-N”
Largest usable signed integer.
MAX-U
( – u ) environment “MAX-U”
Largest usable unsigned integer.
MAX-D
( – d ) environment “MAX-D”
Largest usable signed double.
MAX-UD
( – ud ) environment “MAX-UD”
Largest usable unsigned double.
return-stack-cells
( – n ) environment “return-stack-cells”
Maximum size of the return stack, in cells.
stack-cells
( – n ) environment “stack-cells”
Maximum size of the data stack, in cells.
floating-stack
( – n ) environment “floating-stack”
n is non-zero, showing that Gforth maintains a separate floating-point stack of depth n.
#locals
( – n ) environment “number-locals”
The maximum number of locals in a definition
wordlists
( – n ) environment “wordlists”
the maximum number of wordlists usable in the search order
max-float
( – r ) environment “max-float”
The largest usable floating-point number (implemented as largest finite number in Gforth)
XCHAR-ENCODING
( – addr u ) environment “XCHAR-ENCODING”
Returns a printable ASCII string that reperesents the encoding, and use the preferred MIME name (if any) or the name in http://www.iana.org/assignments/character-sets like “ISO-LATIN-1” or “UTF-8”, with the exception of “ASCII”, where we prefer the alias “ASCII”.
MAX-XCHAR
( – xchar ) environment “MAX-XCHAR”
Maximal value for xchar. This depends on the encoding.
XCHAR-MAXMEM
( – u ) environment “XCHAR-MAXMEM”
Maximal memory consumed by an xchar in address units
Several environemtal queries are there for determining the presence of
the Forth-94 version of a wordset; they all have the stack effect
( -- f )
if the string is present (so the environment?
stack effect for these queries is ( c-addr u -- false / f true
)
.
block
block-ext
double
double-ext
exception
exception-ext
facility
facility-ext
file
file-ext
floating
floating-ext
locals
locals-ext
memory-alloc
memory-alloc-ext
tools
tools-ext
search-order
search-order-ext
string
string-ext
These wordset queries were rarely used and implemented, so Forth-2012
did not introduce a way to query for the Forth-2012 variants of the
wordsets. Instead, the idea is that you use [defined]
(see Interpreter Directives) instead.
Forth-200x (a group that works on the next standard; the documents
that they produce are also called Forth-200x) defines extension
queries for the extension proposals once they finish changing (CfV
stage), so programs using these proposals can check whether a system
has them, and maybe load the reference implementation (if one exists).
If environment?
finds such a query, then the corresponding
proposal on www.forth200x.org is implemented on the system (but
the absence tells you nothing, as usual with environment?
).
These queries have the stack effect ( -- )
, which means that
for them environment?
has the stack effect ( c-addr u --
false / true )
, which is more convenient than that of wordset
queries. A number of these proposals have been incorporated into
Forth-2012. The extension queries are also not particularly popular
among Forth system implementors, so going for [defined]
may be
the better approach. Anyway, Gforth implements the following
extension queries:
X:2value
X:buffer
X:deferred
X:defined
X:ekeys
X:escaped-strings
X:extension-query
X:fp-stack
X:ftrunc
X:fvalue
X:locals
X:n-to-r
X:number-prefixes
X:parse-name
X:required
X:s-escape-quote
X:s-to-f
X:structures
X:synonym
X:text-substitution
X:throw-iors
X:traverse-wordlist
X:xchar
In addition, Gforth implements the following Gforth-specific queries:
gforth
( – c-addr u ) gforth-environment “gforth”
Counted string representing a version string for this version of Gforth (for versions>0.3.0). The version strings of the various versions are guaranteed to be ordered lexicographically.
os-class
( – c-addr u ) gforth-environment “os-class”
Counted string representing a description of the host operating system.
os-type
( – c-addr u ) gforth-environment “os-type”
Counted string equal to "$host_os"
The Standard requires that the header space used for environmental queries be distinct from the header space used for definitions.
Typically, a Forth system supports environmental queries by creating a set of definitions in a wordlist that is only used for environmental queries; that is what Gforth does. There is no Standard way of adding definitions to the set of recognised environmental queries, but in Gforth and other systems that use the wordlist mechanism, the wordlist used to honour environmental queries can be manipulated just like any other word list.
environment-wordlist
( – wid ) gforth-0.2 “environment-wordlist”
wid identifies the word list that is searched by environmental queries (present in SwiftForth and VFX).
environment
( – ) gforth-0.6 “environment”
A vocabulary for environment-wordlist
(present in Win32Forth
and VFX).
Here are some examples of using environmental queries:
s" address-unit-bits" environment? 0= [IF] cr .( environmental attribute address-units-bits unknown... ) cr [ELSE] drop \ ensure balanced stack effect [THEN] \ this might occur in the prelude of a standard program that uses THROW s" exception" environment? [IF] 0= [IF] : throw abort" exception thrown" ; [THEN] [ELSE] \ we don't know, so make sure : throw abort" exception thrown" ; [THEN] s" gforth" environment? [IF] .( Gforth version ) TYPE [ELSE] .( Not Gforth..) [THEN] \ a program using v* s" gforth" environment? [IF] s" 0.5.0" compare 0< [IF] \ v* is a primitive since 0.5.0 : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r ) >r swap 2swap swap 0e r> 0 ?DO dup f@ over + 2swap dup f@ f* f+ over + 2swap LOOP 2drop 2drop ; [THEN] [ELSE] \ : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r ) ... [THEN]
Here is an example of adding a definition to the environment word list:
get-current environment-wordlist set-current true constant block true constant block-ext set-current
You can see what definitions are in the environment word list like this:
environment-wordlist wordlist-words