RfD - FVALUE
Marcel Hendrix, August 25, 2006
* First draft *
Rationale
=========
Problem
-------
The word VALUE was considered useful enough to be included in ANS94.
A search through 4827 source files shows 532 occurences of VARIABLE
versus 4241 uses of VALUE. It would be obviously useful to have a
variant of VALUE that works for floating-point values.
The main idea behind FVALUE is that fetching a variable is more
frequent than changing it. Therefore both readibility of source code
and efficiency of execution can be achieved by making 'F@' the default
action of FVALUE.
Current practice
----------------
The proposed form of FVALUE has been in use in tForth, iForth, and their
predecessors since 1985. FVALUE (with TO) is also in use for Mops and
MacForth. The systems mentioned define more TO-like words that work on
values, e.g. +TO -TO CLEAR, with obvious meanings.
This proposal does not propose to standardize on these extensions.
Solution
--------
Although many people have objected to parsing words, parsing
permits the host system the most flexibility in implementation
and is thus the preferred solution (see also TO).
The syntax is:
123e0 FVALUE fdata
to define <fdata> as a floating-point value initialized to <123e0>.
To access the value of fdata:
fdata 2e0 F+ F. <cr> 125.000000 ok
To change fdata:
fdata 2e0 F+ TO fdata fdata F. <cr> 125.000000 ok
Proposal
========
12.6.1.xxxx FVALUE "f-value" FLOATING
( F: x -- ) ( "<spaces>name" -- )
Skip leading space delimiters. Parse name delimited by a space. Create
a definition for name with the execution semantics defined below, with
an initial value equal to x.
name is referred to as an "f-value".
name Execution: ( F: -- x )
Place x on the FP stack. The value of x is that given when name was
created, until the phrase x TO name is executed, causing a new value of
x to be associated with name.
See: 3.4.1 Parsing.
6.2.2295 TO CORE EXT
Interpretation: ( x "<spaces>name" -- ) or ( F: x -- ) ( "<spaces>name" -- )
Skip leading spaces and parse name delimited by a space. Store x in
name. An ambiguous condition exists if name was not defined by VALUE or FVALUE.
Compilation: ( "<spaces>name" -- )
Skip leading spaces and parse name delimited by a space. Append the
run-time semantics given below to the current definition. An ambiguous
condition exists if name was not defined by VALUE or FVALUE.
Run-time: ( x -- ) or ( F: x -- )
Store x in name.
Note: An ambiguous condition exists if either POSTPONE or [COMPILE] is applied to TO.
See: 6.2.2405 VALUE, 12.6.1.xxxx FVALUE, 13.6.1.2295 TO.
13.6.1.2295 TO LOCAL
Extend the semantics of 6.2.2295 TO to be:
Interpretation: ( x "<spaces>name" -- ) or ( F: x -- ) ( "<spaces>name" -- )
Skip leading spaces and parse name delimited by a space. Store x in
name. An ambiguous condition exists if name was not defined by VALUE or FVALUE.
Compilation: ( "<spaces>name" -- )
Skip leading spaces and parse name delimited by a space. Append the
run-time semantics given below to the current definition. An ambiguous
condition exists if name was not defined by either VALUE, FVALUE or (LOCAL).
Run-time: ( x -- ) or ( F: x -- )
Store x in name.
Note:
An ambiguous condition exists if either POSTPONE or [COMPILE] is applied to TO.
See: 3.4.1 Parsing, 6.2.2295 TO, 6.2.2405 VALUE, 12.6.1.xxxx FVALUE, 13.6.1.0086 (LOCAL).
Labelling
=========
TBD
Reference Implementation
========================
The implementation of FVALUE requires carnal knowledge of the host
implementation, which is the main reason why it should be standardized.
The implementation below disregards the issue that TO should also
work for integer VALUEs and locals.
: FVALUE CREATE F, ( F: r -- ) DOES> F@ ; ( F: -- r )
: TO ( F: r -- ) ( "<spaces>name" -- )
' >BODY
STATE @ IF POSTPONE LITERAL POSTPONE F!
ELSE F!
THEN ; IMMEDIATE
Test Cases
==========
123e FVALUE fdata
2 VALUE idata
: foo ( -- )
idata LOCALS| ldata |
ldata . idata 2* TO ldata ldata .
idata 1 D>F TO fdata fdata F.
fdata 33e F+ F>D D>S TO idata idata .
ldata idata + fdata F>D D>S + . ;
foo <cr> 2 4 4.294967e9 35 41 ok